Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/demo-zk-books/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyyMMdd</maven.build.timestamp.format>

<tools.version>26.5.0</tools.version>
<tools.version>26.5.1</tools.version>

</properties>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
import mybookstore.domain.Book;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import tools.dynamia.domain.jpa.JpaCrudServiceRepository;

import java.util.Optional;

Expand Down
6 changes: 3 additions & 3 deletions extensions/dashboard/sources/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<parent>
<groupId>tools.dynamia.modules</groupId>
<artifactId>tools.dynamia.modules.parent</artifactId>
<version>26.5.0</version>
<version>26.5.1</version>
<relativePath>../../pom.xml</relativePath>
</parent>

Expand All @@ -38,12 +38,12 @@
<dependency>
<groupId>tools.dynamia</groupId>
<artifactId>tools.dynamia.zk</artifactId>
<version>26.5.0</version>
<version>26.5.1</version>
</dependency>
<dependency>
<groupId>tools.dynamia.modules</groupId>
<artifactId>tools.dynamia.modules.saas.api</artifactId>
<version>26.5.0</version>
<version>26.5.1</version>
</dependency>
</dependencies>

Expand Down
6 changes: 3 additions & 3 deletions extensions/email-sms/sources/core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<parent>
<artifactId>tools.dynamia.modules.email.parent</artifactId>
<groupId>tools.dynamia.modules</groupId>
<version>26.5.0</version>
<version>26.5.1</version>
</parent>

<artifactId>tools.dynamia.modules.email</artifactId>
Expand All @@ -50,12 +50,12 @@
<dependency>
<groupId>tools.dynamia</groupId>
<artifactId>tools.dynamia.domain.jpa</artifactId>
<version>26.5.0</version>
<version>26.5.1</version>
</dependency>
<dependency>
<groupId>tools.dynamia</groupId>
<artifactId>tools.dynamia.templates</artifactId>
<version>26.5.0</version>
<version>26.5.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
Expand Down
4 changes: 2 additions & 2 deletions extensions/email-sms/sources/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<parent>
<groupId>tools.dynamia.modules</groupId>
<artifactId>tools.dynamia.modules.parent</artifactId>
<version>26.5.0</version>
<version>26.5.1</version>
<relativePath>../../pom.xml</relativePath>
</parent>

Expand Down Expand Up @@ -85,7 +85,7 @@
<dependency>
<groupId>tools.dynamia.modules</groupId>
<artifactId>tools.dynamia.modules.saas.jpa</artifactId>
<version>26.5.0</version>
<version>26.5.1</version>
</dependency>


Expand Down
6 changes: 3 additions & 3 deletions extensions/email-sms/sources/ui/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<artifactId>tools.dynamia.modules.email.parent</artifactId>
<groupId>tools.dynamia.modules</groupId>
<version>26.5.0</version>
<version>26.5.1</version>
</parent>

<name>DynamiaModules - Email UI</name>
Expand All @@ -34,12 +34,12 @@
<dependency>
<groupId>tools.dynamia</groupId>
<artifactId>tools.dynamia.zk</artifactId>
<version>26.5.0</version>
<version>26.5.1</version>
</dependency>
<dependency>
<groupId>tools.dynamia.modules</groupId>
<artifactId>tools.dynamia.modules.email</artifactId>
<version>26.5.0</version>
<version>26.5.1</version>
</dependency>
<dependency>
<groupId>tools.dynamia.zk.addons</groupId>
Expand Down
2 changes: 1 addition & 1 deletion extensions/entity-files/packages/files-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dynamia-tools/files-sdk",
"version": "26.5.0",
"version": "26.5.1",
"website": "https://dynamia.tools",
"description": "TypeScript/JavaScript client SDK for the Dynamia Entity Files extension REST API",
"keywords": [
Expand Down
110 changes: 109 additions & 1 deletion extensions/entity-files/packages/simple-file-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,117 @@ Each bucket also contains an internal `.sfs/` directory:
- **Path traversal protection**: canonical path validation on every request
- **No public access**: no anonymous or public bucket support

## Requirements

| Requirement | Minimum version |
|---|---|
| Node.js | **18.17.0** |
| npm | 9+ (or pnpm 8+) |

> **Why 18.17.0?** The `sharp` native image-processing library requires exactly `^18.17.0` as the lowest Node 18 patch that ships a compatible binary. All other dependencies support Node ≥ 18.

## Embedded Usage

You can start SFS programmatically inside your own Node.js application — no CLI needed.

### Installation

```bash
npm install @dynamia-tools/simple-file-server
```

### Minimal example

```js
// index.js (type: "module")
import { startServer } from '@dynamia-tools/simple-file-server'

// Reads configuration from the .sfs/ directory in process.cwd().
// Provision buckets and identities first with the CLI, or do it
// programmatically (see "Full programmatic setup" below).
startServer({
host: process.env.SFS_HOST ?? '0.0.0.0',
port: parseInt(process.env.SFS_PORT ?? '8080', 10),
}).catch((err) => {
console.error('Fatal error during startup:', err)
process.exit(1)
})
```

### Full programmatic setup

Use `createRuntime` to bootstrap services and configure buckets/identities entirely in code:

```js
import path from 'node:path'
import { createRuntime, createServer } from '@dynamia-tools/simple-file-server'

const runtime = await createRuntime({
dataDir: path.join(process.cwd(), '.sfs'),
host: '0.0.0.0',
port: 8080,
logLevel: 'info',
})

const { config, bucketService, storageService, thumbnailService,
identityService, operationalLogger } = runtime

// Create a bucket (idempotent pattern)
if (!await bucketService.find('documents')) {
await bucketService.create('documents', '/mnt/storage/documents')
}

// Create an identity (idempotent pattern)
if (!await identityService.find('app-user')) {
await identityService.create('app-user', process.env.APP_SECRET ?? 'changeme')
}

// Grant permissions
await identityService.grant('app-user', {
bucket: 'documents',
prefixes: ['/'], // entire bucket
permissions: ['read', 'write', 'delete'],
})

// Validate buckets and start the server
await bucketService.validateStartup()

const server = await createServer({
config, bucketService, storageService,
thumbnailService, identityService, operationalLogger,
})

process.on('SIGTERM', async () => { await server.close(); process.exit(0) })
process.on('SIGINT', async () => { await server.close(); process.exit(0) })

await server.listen({ host: config.host, port: config.port })
```

### Available exports

| Export | Description |
|---|---|
| `startServer(overrides?)` | One-call bootstrap: creates runtime + server + starts listening |
| `createRuntime(overrides?)` | Initialises services and data dirs, returns the `SFSRuntime` object |
| `createServer(runtime)` | Builds and returns the Fastify instance (does not call `.listen`) |
| `BucketService` | Manage bucket definitions |
| `IdentityService` | Manage identities and grants |
| `StorageService` | Low-level file upload / download / list |
| `ThumbnailService` | On-the-fly image thumbnails via Sharp |
| `OperationalLogger` | Structured JSONL access + error logs |

### Environment variables

| Variable | Default | Description |
|---|---|---|
| `SFS_DATA_DIR` | `<cwd>/.sfs` | Where SFS stores config, identities and buckets |
| `SFS_HOST` | `0.0.0.0` | Bind host |
| `SFS_PORT` | `8080` | Bind port |
| `SFS_LOG_LEVEL` | `info` | Pino log level (`trace` `debug` `info` `warn` `error`) |

## Technology Stack

- **Node.js 22+** with TypeScript (strict mode)
- **Node.js 18.17+** with TypeScript (strict mode)
- **Fastify** for high-throughput HTTP
- **Pino** for structured JSON logging
- **Sharp** for efficient thumbnail generation
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* simple-file-server — Embedded Mode Example
*
* Starts the server using the configuration already present in the
* current working directory (.sfs/ folder). No extra setup is done
* here — use the CLI (`sfs create bucket …`, `sfs create identity …`)
* to provision buckets and identities beforehand.
*
* Configuration via environment variables (all optional):
* SFS_HOST – bind host (default: 0.0.0.0)
* SFS_PORT – bind port (default: 8500)
* SFS_LOG_LEVEL – log level (default: info)
*
* Usage:
* npm install
* npm start
*/
import { startServer } from '@dynamia-tools/simple-file-server'

const PORT = parseInt(process.env.SFS_PORT ?? '8500', 10)
const HOST = process.env.SFS_HOST ?? '0.0.0.0'

startServer({ port: PORT, host: HOST }).catch((err) => {
console.error('Fatal error during startup:', err)
process.exit(1)
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "sfs-embedded-example",
"version": "1.0.0",
"description": "Example: using simple-file-server in embedded mode (programmatic API)",
"type": "module",
"scripts": {
"start": "node index.js",
"start:debug": "node --inspect index.js"
},
"dependencies": {
"@dynamia-tools/simple-file-server": "^26.5.0"
},
"engines": {
"node": ">=18.17.0"
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dynamia-tools/simple-file-server",
"version": "26.5.0",
"version": "26.5.1",
"description": "Standalone filesystem-native file server with a minimal S3-style API for secure server-to-server file operations",
"keywords": [
"dynamia",
Expand Down Expand Up @@ -57,7 +57,7 @@
"commander": "^13.1.0",
"fastify": "^5.3.0",
"fastify-plugin": "^5.1.0",
"file-type": "^21.0.0",
"file-type": "^20.0.0",
"pino": "^9.7.0",
"pino-pretty": "^13.0.0",
"sharp": "^0.34.1",
Expand All @@ -71,6 +71,6 @@
"vitest": "^3.0.0"
},
"engines": {
"node": ">=22.0.0"
"node": ">=18.17.0"
}
}
Loading
Loading