Oleq Files

Examples

HTML, Next.js, and NestJS upload examples with @oleq-ai/file-manager

Never put OLEQFILES_API_KEY in browser code. The browser posts to your backend; your backend runs the SDK.

StackClientServer
HTMLPlain form / fetchNest (or any) upload route
Next.js@oleq-ai/file-manager/react hookApp Router Route Handler
NestJSHTML or React@oleq-ai/file-manager/nest module + controller

HTML

Post multipart to your API. Point /upload at the NestJS controller below (or an equivalent Express / Next route).

With fetch

Simple path — no upload progress (fetch does not expose it).

public/upload-fetch.html
<form id="form">
  <input type="file" name="file" accept="image/*" required />
  <button type="submit">Upload</button>
  <p id="status"></p>
</form>

<script>
  const form = document.getElementById('form');
  const status = document.getElementById('status');

  form.addEventListener('submit', async (e) => {
    e.preventDefault();
    const file = form.file.files[0];
    if (!file) return;

    const body = new FormData();
    body.append('file', file);

    status.textContent = 'Uploading…';

    try {
      const res = await fetch('/upload', { method: 'POST', body });
      const data = await res.json();
      if (!res.ok) {
        status.textContent = data.error || 'Upload failed';
        return;
      }
      status.textContent = 'Done';
      console.log(data.id, data.src);
    } catch {
      status.textContent = 'Upload failed';
    }
  });
</script>

With progress (XMLHttpRequest)

Use XHR when you need a progress bar.

public/upload-progress.html
<form id="form">
  <input type="file" name="file" accept="image/*" required />
  <button type="submit">Upload</button>
  <progress id="bar" value="0" max="100" hidden></progress>
  <p id="error"></p>
</form>

<script>
  const form = document.getElementById('form');
  const bar = document.getElementById('bar');
  const errorEl = document.getElementById('error');

  form.addEventListener('submit', (e) => {
    e.preventDefault();
    const file = form.file.files[0];
    if (!file) return;

    const body = new FormData();
    body.append('file', file);

    bar.hidden = false;
    bar.value = 0;
    errorEl.textContent = '';

    const xhr = new XMLHttpRequest();
    xhr.open('POST', '/upload');
    xhr.upload.onprogress = (ev) => {
      if (ev.lengthComputable) {
        bar.value = Math.round((ev.loaded / ev.total) * 100);
      }
    };
    xhr.onload = () => {
      const data = JSON.parse(xhr.responseText || '{}');
      if (xhr.status >= 200 && xhr.status < 300) {
        console.log(data.id, data.src);
      } else {
        errorEl.textContent = data.error || 'Upload failed';
      }
    };
    xhr.onerror = () => {
      errorEl.textContent = 'Upload failed';
    };
    xhr.send(body);
  });
</script>

Next.js

Client

components/file-upload.tsx
'use client';

import { useOleqFilesUpload } from '@oleq-ai/file-manager/react';

export function FileUpload() {
  const { upload, uploading, progress, error } = useOleqFilesUpload();

  async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const file = (
      e.currentTarget.elements.namedItem('file') as HTMLInputElement
    ).files?.[0];
    if (!file) return;

    const result = await upload(file);
    if (result) console.log(result.id, result.src);
  }

  return (
    <form onSubmit={onSubmit}>
      <input type="file" name="file" accept="image/*" required />
      <button type="submit" disabled={uploading}>
        {uploading ? 'Uploading…' : 'Upload'}
      </button>
      {uploading && <progress value={progress} max={100} />}
      {error && <p>{error}</p>}
    </form>
  );
}

Optional callback:

const { upload } = useOleqFilesUpload({
  endpoint: '/api/upload',
  onProgress: (percent) => console.log(`${percent}%`),
});

Route Handler

app/api/upload/route.ts
import OleqFiles, { OleqFilesError } from '@oleq-ai/file-manager';

const oleqfiles = new OleqFiles();

export async function POST(req: Request) {
  try {
    const form = await req.formData();
    const file = form.get('file');
    if (!(file instanceof File)) {
      return Response.json({ error: 'file is required' }, { status: 400 });
    }

    const result = await oleqfiles.files.upload({
      appId: process.env.OLEQFILES_APP_ID!,
      name: file.name,
      mimeType: file.type || 'application/octet-stream',
      data: file,
    });

    return Response.json({ id: result.id, src: result.src });
  } catch (err) {
    if (err instanceof OleqFilesError) {
      return Response.json({ error: err.message }, { status: err.status });
    }
    throw err;
  }
}

Set OLEQFILES_API_KEY and OLEQFILES_APP_ID in server env only.


NestJS

Install the adapter

pnpm add @oleq-ai/file-manager @nestjs/platform-express

@oleq-ai/file-manager/nest needs @nestjs/common (already in Nest apps). File uploads use Multer via @nestjs/platform-express.

Register the module

app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { OleqFilesModule } from '@oleq-ai/file-manager/nest';
import { UploadController } from './upload.controller';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    OleqFilesModule.forRoot(), // reads OLEQFILES_API_KEY
    // or async:
    // OleqFilesModule.forRootAsync({
    //   inject: [ConfigService],
    //   useFactory: (config: ConfigService) => ({
    //     apiKey: config.get<string>('OLEQFILES_API_KEY'),
    //   }),
    // }),
  ],
  controllers: [UploadController],
})
export class AppModule {}

Upload controller

upload.controller.ts
import {
  BadRequestException,
  Controller,
  HttpException,
  Post,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { OleqFiles, OleqFilesError } from '@oleq-ai/file-manager';

@Controller()
export class UploadController {
  constructor(private readonly oleqfiles: OleqFiles) {}

  @Post('upload')
  @UseInterceptors(FileInterceptor('file'))
  async upload(@UploadedFile() file?: Express.Multer.File) {
    if (!file) throw new BadRequestException({ error: 'file is required' });

    try {
      const result = await this.oleqfiles.files.upload({
        appId: process.env.OLEQFILES_APP_ID!,
        name: file.originalname,
        mimeType: file.mimetype || 'application/octet-stream',
        data: file.buffer,
      });
      return { id: result.id, src: result.src };
    } catch (err) {
      if (err instanceof OleqFilesError) {
        throw new HttpException({ error: err.message }, err.status);
      }
      throw err;
    }
  }
}

Inject OleqFiles anywhere else the same way — list apps, usage, delete, etc.

const { apps } = await this.oleqfiles.apps.list();
const usage = await this.oleqfiles.usage.get();

On this page