Skip to content

Commit 5dd1d57

Browse files
Merge pull request #64 from dynamiatools/feature/simple-file-server-with-node18-support
Feature/simple file server with node18 support
2 parents b49f6ec + a308f90 commit 5dd1d57

65 files changed

Lines changed: 390 additions & 185 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

examples/demo-zk-books/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
<timestamp>${maven.build.timestamp}</timestamp>
4848
<maven.build.timestamp.format>yyyyMMdd</maven.build.timestamp.format>
4949

50-
<tools.version>26.5.0</tools.version>
50+
<tools.version>26.5.1</tools.version>
5151

5252
</properties>
5353

examples/demo-zk-books/src/main/java/mybookstore/repositories/BookRepository.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
import mybookstore.domain.Book;
44
import org.springframework.cache.annotation.Cacheable;
55
import org.springframework.data.jpa.repository.JpaRepository;
6-
import org.springframework.data.repository.PagingAndSortingRepository;
76
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
8-
import tools.dynamia.domain.jpa.JpaCrudServiceRepository;
97

108
import java.util.Optional;
119

extensions/dashboard/sources/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<parent>
2424
<groupId>tools.dynamia.modules</groupId>
2525
<artifactId>tools.dynamia.modules.parent</artifactId>
26-
<version>26.5.0</version>
26+
<version>26.5.1</version>
2727
<relativePath>../../pom.xml</relativePath>
2828
</parent>
2929

@@ -38,12 +38,12 @@
3838
<dependency>
3939
<groupId>tools.dynamia</groupId>
4040
<artifactId>tools.dynamia.zk</artifactId>
41-
<version>26.5.0</version>
41+
<version>26.5.1</version>
4242
</dependency>
4343
<dependency>
4444
<groupId>tools.dynamia.modules</groupId>
4545
<artifactId>tools.dynamia.modules.saas.api</artifactId>
46-
<version>26.5.0</version>
46+
<version>26.5.1</version>
4747
</dependency>
4848
</dependencies>
4949

extensions/email-sms/sources/core/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<parent>
2424
<artifactId>tools.dynamia.modules.email.parent</artifactId>
2525
<groupId>tools.dynamia.modules</groupId>
26-
<version>26.5.0</version>
26+
<version>26.5.1</version>
2727
</parent>
2828

2929
<artifactId>tools.dynamia.modules.email</artifactId>
@@ -50,12 +50,12 @@
5050
<dependency>
5151
<groupId>tools.dynamia</groupId>
5252
<artifactId>tools.dynamia.domain.jpa</artifactId>
53-
<version>26.5.0</version>
53+
<version>26.5.1</version>
5454
</dependency>
5555
<dependency>
5656
<groupId>tools.dynamia</groupId>
5757
<artifactId>tools.dynamia.templates</artifactId>
58-
<version>26.5.0</version>
58+
<version>26.5.1</version>
5959
</dependency>
6060
<dependency>
6161
<groupId>org.springframework</groupId>

extensions/email-sms/sources/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<parent>
2424
<groupId>tools.dynamia.modules</groupId>
2525
<artifactId>tools.dynamia.modules.parent</artifactId>
26-
<version>26.5.0</version>
26+
<version>26.5.1</version>
2727
<relativePath>../../pom.xml</relativePath>
2828
</parent>
2929

@@ -85,7 +85,7 @@
8585
<dependency>
8686
<groupId>tools.dynamia.modules</groupId>
8787
<artifactId>tools.dynamia.modules.saas.jpa</artifactId>
88-
<version>26.5.0</version>
88+
<version>26.5.1</version>
8989
</dependency>
9090

9191

extensions/email-sms/sources/ui/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<parent>
2323
<artifactId>tools.dynamia.modules.email.parent</artifactId>
2424
<groupId>tools.dynamia.modules</groupId>
25-
<version>26.5.0</version>
25+
<version>26.5.1</version>
2626
</parent>
2727

2828
<name>DynamiaModules - Email UI</name>
@@ -34,12 +34,12 @@
3434
<dependency>
3535
<groupId>tools.dynamia</groupId>
3636
<artifactId>tools.dynamia.zk</artifactId>
37-
<version>26.5.0</version>
37+
<version>26.5.1</version>
3838
</dependency>
3939
<dependency>
4040
<groupId>tools.dynamia.modules</groupId>
4141
<artifactId>tools.dynamia.modules.email</artifactId>
42-
<version>26.5.0</version>
42+
<version>26.5.1</version>
4343
</dependency>
4444
<dependency>
4545
<groupId>tools.dynamia.zk.addons</groupId>

extensions/entity-files/packages/files-sdk/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@dynamia-tools/files-sdk",
3-
"version": "26.5.0",
3+
"version": "26.5.1",
44
"website": "https://dynamia.tools",
55
"description": "TypeScript/JavaScript client SDK for the Dynamia Entity Files extension REST API",
66
"keywords": [

extensions/entity-files/packages/simple-file-server/README.md

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,117 @@ Each bucket also contains an internal `.sfs/` directory:
246246
- **Path traversal protection**: canonical path validation on every request
247247
- **No public access**: no anonymous or public bucket support
248248

249+
## Requirements
250+
251+
| Requirement | Minimum version |
252+
|---|---|
253+
| Node.js | **18.17.0** |
254+
| npm | 9+ (or pnpm 8+) |
255+
256+
> **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.
257+
258+
## Embedded Usage
259+
260+
You can start SFS programmatically inside your own Node.js application — no CLI needed.
261+
262+
### Installation
263+
264+
```bash
265+
npm install @dynamia-tools/simple-file-server
266+
```
267+
268+
### Minimal example
269+
270+
```js
271+
// index.js (type: "module")
272+
import { startServer } from '@dynamia-tools/simple-file-server'
273+
274+
// Reads configuration from the .sfs/ directory in process.cwd().
275+
// Provision buckets and identities first with the CLI, or do it
276+
// programmatically (see "Full programmatic setup" below).
277+
startServer({
278+
host: process.env.SFS_HOST ?? '0.0.0.0',
279+
port: parseInt(process.env.SFS_PORT ?? '8080', 10),
280+
}).catch((err) => {
281+
console.error('Fatal error during startup:', err)
282+
process.exit(1)
283+
})
284+
```
285+
286+
### Full programmatic setup
287+
288+
Use `createRuntime` to bootstrap services and configure buckets/identities entirely in code:
289+
290+
```js
291+
import path from 'node:path'
292+
import { createRuntime, createServer } from '@dynamia-tools/simple-file-server'
293+
294+
const runtime = await createRuntime({
295+
dataDir: path.join(process.cwd(), '.sfs'),
296+
host: '0.0.0.0',
297+
port: 8080,
298+
logLevel: 'info',
299+
})
300+
301+
const { config, bucketService, storageService, thumbnailService,
302+
identityService, operationalLogger } = runtime
303+
304+
// Create a bucket (idempotent pattern)
305+
if (!await bucketService.find('documents')) {
306+
await bucketService.create('documents', '/mnt/storage/documents')
307+
}
308+
309+
// Create an identity (idempotent pattern)
310+
if (!await identityService.find('app-user')) {
311+
await identityService.create('app-user', process.env.APP_SECRET ?? 'changeme')
312+
}
313+
314+
// Grant permissions
315+
await identityService.grant('app-user', {
316+
bucket: 'documents',
317+
prefixes: ['/'], // entire bucket
318+
permissions: ['read', 'write', 'delete'],
319+
})
320+
321+
// Validate buckets and start the server
322+
await bucketService.validateStartup()
323+
324+
const server = await createServer({
325+
config, bucketService, storageService,
326+
thumbnailService, identityService, operationalLogger,
327+
})
328+
329+
process.on('SIGTERM', async () => { await server.close(); process.exit(0) })
330+
process.on('SIGINT', async () => { await server.close(); process.exit(0) })
331+
332+
await server.listen({ host: config.host, port: config.port })
333+
```
334+
335+
### Available exports
336+
337+
| Export | Description |
338+
|---|---|
339+
| `startServer(overrides?)` | One-call bootstrap: creates runtime + server + starts listening |
340+
| `createRuntime(overrides?)` | Initialises services and data dirs, returns the `SFSRuntime` object |
341+
| `createServer(runtime)` | Builds and returns the Fastify instance (does not call `.listen`) |
342+
| `BucketService` | Manage bucket definitions |
343+
| `IdentityService` | Manage identities and grants |
344+
| `StorageService` | Low-level file upload / download / list |
345+
| `ThumbnailService` | On-the-fly image thumbnails via Sharp |
346+
| `OperationalLogger` | Structured JSONL access + error logs |
347+
348+
### Environment variables
349+
350+
| Variable | Default | Description |
351+
|---|---|---|
352+
| `SFS_DATA_DIR` | `<cwd>/.sfs` | Where SFS stores config, identities and buckets |
353+
| `SFS_HOST` | `0.0.0.0` | Bind host |
354+
| `SFS_PORT` | `8080` | Bind port |
355+
| `SFS_LOG_LEVEL` | `info` | Pino log level (`trace` `debug` `info` `warn` `error`) |
356+
249357
## Technology Stack
250358
251-
- **Node.js 22+** with TypeScript (strict mode)
359+
- **Node.js 18.17+** with TypeScript (strict mode)
252360
- **Fastify** for high-throughput HTTP
253361
- **Pino** for structured JSON logging
254362
- **Sharp** for efficient thumbnail generation
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* simple-file-server — Embedded Mode Example
3+
*
4+
* Starts the server using the configuration already present in the
5+
* current working directory (.sfs/ folder). No extra setup is done
6+
* here — use the CLI (`sfs create bucket …`, `sfs create identity …`)
7+
* to provision buckets and identities beforehand.
8+
*
9+
* Configuration via environment variables (all optional):
10+
* SFS_HOST – bind host (default: 0.0.0.0)
11+
* SFS_PORT – bind port (default: 8500)
12+
* SFS_LOG_LEVEL – log level (default: info)
13+
*
14+
* Usage:
15+
* npm install
16+
* npm start
17+
*/
18+
import { startServer } from '@dynamia-tools/simple-file-server'
19+
20+
const PORT = parseInt(process.env.SFS_PORT ?? '8500', 10)
21+
const HOST = process.env.SFS_HOST ?? '0.0.0.0'
22+
23+
startServer({ port: PORT, host: HOST }).catch((err) => {
24+
console.error('Fatal error during startup:', err)
25+
process.exit(1)
26+
})
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "sfs-embedded-example",
3+
"version": "1.0.0",
4+
"description": "Example: using simple-file-server in embedded mode (programmatic API)",
5+
"type": "module",
6+
"scripts": {
7+
"start": "node index.js",
8+
"start:debug": "node --inspect index.js"
9+
},
10+
"dependencies": {
11+
"@dynamia-tools/simple-file-server": "^26.5.0"
12+
},
13+
"engines": {
14+
"node": ">=18.17.0"
15+
}
16+
}
17+

0 commit comments

Comments
 (0)