@edgestore/server
Version:
Upload files with ease from React/Next.js
217 lines • 7.13 kB
TypeScript
import { type AnyBuilder, type AnyRouter, type InferBucketPathKeys, type InferBucketPathObject, type InferMetadataObject, type Prettify, type Simplify } from '@edgestore/shared';
import { type z, type ZodNever } from 'zod';
import { type Comparison } from '..';
export type GetFileRes<TBucket extends AnyBuilder> = {
url: string;
size: number;
uploadedAt: Date;
metadata: InferMetadataObject<TBucket>;
path: InferBucketPathObject<TBucket>;
};
export type UploadOptions = {
/**
* e.g. 'my-file-name.jpg'
*
* By default, a unique file name will be generated for each upload.
* If you want to use a custom file name, you can use this option.
* If you use the same file name for multiple uploads, the previous file will be overwritten.
* But it might take some time for the CDN cache to be cleared.
* So maybe you will keep seeing the old file for a while.
*
* If you want to replace an existing file, immediately leave the `manualFileName` option empty and use the `replaceTargetUrl` option.
*/
manualFileName?: string;
/**
* Use this to replace an existing file.
* It will automatically delete the existing file when the upload is complete.
*/
replaceTargetUrl?: string;
/**
* If true, the file needs to be confirmed by using the `confirmUpload` function.
* If the file is not confirmed within 24 hours, it will be deleted.
*
* This is useful for pages where the file is uploaded as soon as it is selected,
* but the user can leave the page without submitting the form.
*
* This avoids unnecessary zombie files in the bucket.
*/
temporary?: boolean;
};
type TextContent = string;
type BlobContent = {
blob: Blob;
extension: string;
};
type UrlContent = {
url: string;
extension: string;
};
export type UploadFileRequest<TBucket extends AnyBuilder> = {
/**
* Can be a string, a blob or an url.
*
* If it's a string, it will be converted to a blob with the type `text/plain`.
*
* @example
* // string
* content: "some text"
*
* @example
* // blob
* content: {
* blob: new Blob([text], { type: "text/csv" }),
* extension: "csv",
* }
*
* @example
* // url
* content: {
* url: "https://example.com/my-file.csv",
* extension: "csv",
* }
*/
content: TextContent | BlobContent | UrlContent;
options?: UploadOptions;
} & (TBucket['$config']['ctx'] extends Record<string, never> ? {} : {
ctx: TBucket['$config']['ctx'];
}) & (TBucket['_def']['input'] extends ZodNever ? {} : {
input: z.infer<TBucket['_def']['input']>;
});
export type UploadFileRes<TBucket extends AnyBuilder> = TBucket['_def']['type'] extends 'IMAGE' ? {
url: string;
thumbnailUrl: string | null;
size: number;
metadata: InferMetadataObject<TBucket>;
path: InferBucketPathObject<TBucket>;
pathOrder: (keyof InferBucketPathObject<TBucket>)[];
} : {
url: string;
size: number;
metadata: InferMetadataObject<TBucket>;
path: InferBucketPathObject<TBucket>;
pathOrder: (keyof InferBucketPathObject<TBucket>)[];
};
type Filter<TBucket extends AnyBuilder> = {
AND?: Filter<TBucket>[];
OR?: Filter<TBucket>[];
uploadedAt?: Comparison<Date>;
path?: {
[K in InferBucketPathKeys<TBucket>]?: Comparison;
};
metadata?: {
[K in keyof InferMetadataObject<TBucket>]?: Comparison;
};
};
export type ListFilesRequest<TBucket extends AnyBuilder> = {
filter?: Filter<TBucket>;
pagination?: {
currentPage: number;
pageSize: number;
};
};
export type ListFilesResponse<TBucket extends AnyBuilder> = {
data: TBucket['_def']['type'] extends 'IMAGE' ? {
url: string;
thumbnailUrl: string | null;
size: number;
uploadedAt: Date;
metadata: InferMetadataObject<TBucket>;
path: InferBucketPathObject<TBucket>;
}[] : {
url: string;
size: number;
uploadedAt: Date;
metadata: InferMetadataObject<TBucket>;
path: InferBucketPathObject<TBucket>;
}[];
pagination: {
currentPage: number;
totalPages: number;
totalCount: number;
};
};
type EdgeStoreClient<TRouter extends AnyRouter> = {
[K in keyof TRouter['buckets']]: {
getFile: (params: {
url: string;
}) => Promise<GetFileRes<TRouter['buckets'][K]>>;
/**
* Use this function to upload a file to the bucket directly from your backend.
*
* @example
* ```ts
* // simple example
* await backendClient.myBucket.upload({
* content: "some text",
* });
* ```
*
* @example
* ```ts
* // complete example
* await backendClient.myBucket.upload({
* content: {
* blob: new Blob([text], { type: "text/csv" }),
* extension: "csv",
* },
* options: {
* temporary: true,
* replaceTargetUrl: replaceUrl,
* manualFileName: "test.csv",
* },
* ctx: {
* userId: "123",
* userRole: "admin",
* },
* input: {
* type: "post",
* },
* });
* ```
*/
upload: (params: UploadFileRequest<TRouter['buckets'][K]>) => Promise<Prettify<UploadFileRes<TRouter['buckets'][K]>>>;
/**
* Confirm a temporary file upload directly from your backend.
*/
confirmUpload: (params: {
url: string;
}) => Promise<{
success: boolean;
}>;
/**
* Programmatically delete a file directly from your backend.
*/
deleteFile: (params: {
url: string;
}) => Promise<{
success: boolean;
}>;
/**
* List files in a bucket.
*
* You can also filter the results by passing a filter object.
* The results are paginated.
*/
listFiles: (params?: ListFilesRequest<TRouter['buckets'][K]>) => Promise<Prettify<ListFilesResponse<TRouter['buckets'][K]>>>;
};
};
export declare function initEdgeStoreClient<TRouter extends AnyRouter>(config: {
router: TRouter;
accessKey?: string;
secretKey?: string;
/**
* The base URL of your application.
*
* This is only needed for getting protected files in a development environment.
*
* @example http://localhost:3000/api/edgestore
*/
baseUrl?: string;
}): EdgeStoreClient<TRouter>;
export type InferClientResponse<TRouter extends AnyRouter> = {
[TBucketName in keyof TRouter['buckets']]: {
[TClienFn in keyof EdgeStoreClient<TRouter>[TBucketName]]: Simplify<Awaited<ReturnType<EdgeStoreClient<TRouter>[TBucketName][TClienFn] extends (...args: any) => any ? EdgeStoreClient<TRouter>[TBucketName][TClienFn] : never>>>;
};
};
export {};
//# sourceMappingURL=index.d.ts.map