Arcwayv0.3.0

File Storage

File read, write, list, and delete with local and S3 drivers

File storage. Available via ctx.files.

// Write a file (string or Buffer)
await ctx.files.write('avatars/user-123.jpg', imageBuffer);

// Read a file (returns Buffer or null)
const buffer = await ctx.files.read('avatars/user-123.jpg');

// Delete a file (no error if missing)
await ctx.files.delete('avatars/user-123.jpg');

// List files under a prefix
const fileList = await ctx.files.list('avatars/');
// ['avatars/user-123.jpg', 'avatars/user-456.jpg']

// Check existence
const exists = await ctx.files.exists('avatars/user-123.jpg');

File Upload Example

// api/upload.js
export const POST = {
  handler: async (ctx) => {
    const { files } = ctx;
    const { filename, data } = ctx.req.body; // Base64 or buffer
    const path = `uploads/${Date.now()}-${filename}`;
    await files.write(path, Buffer.from(data, 'base64'));
    return { data: { path } };
  },
};

Namespacing

Create a namespaced file store:

const avatars = ctx.files.withNamespace('avatars');
await avatars.write('user-123.jpg', buffer);  // Stored at 'avatars/user-123.jpg'
await avatars.list('');                        // Lists only files under 'avatars/'

Path Security

Both drivers enforce path traversal protection — paths containing .. or starting with / are rejected.

File Storage Drivers

Local (default) — stores files on the filesystem under .build/storage/:

export default {
  files: {
    driver: 'local',
    local: {
      root: '.build/storage', // Default
    },
  },
};
  • Automatically creates directories on write
  • list() recursively walks subdirectories
  • Paths normalized to forward slashes

S3 — AWS S3 or S3-compatible storage (MinIO, DigitalOcean Spaces, etc.):

export default {
  files: {
    driver: 's3',
    s3: {
      bucket: 'my-bucket',
      region: 'us-east-1',           // Default
      endpoint: 'https://...',       // Optional: custom S3-compatible endpoint
      forcePathStyle: true,          // Optional: for MinIO compatibility
      credentials: {
        accessKeyId: process.env.AWS_ACCESS_KEY_ID,
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
      },
    },
  },
};

On this page