Skip to content

Latest commit

 

History

History

README.md

@itxtech/fd-server

FlashDetector / FDWebServer compatibility server for FlashMaster Classic. It uses the current fdnext engine and bundled resources while returning legacy HTTP response shapes.

Cloudflare Workers is the preferred deployment target. Node.js, PM2, and systemd support local development, self-hosting, and reverse proxies. For the modern /parts/*, /identifiers/*, and /capabilities API, use @itxtech/fdnext-server or the repository's Workers adapter.

Quick start

Use Node.js 24.11+ and pnpm 12+:

pnpm add @itxtech/fd-server
pnpm exec fd-server --host 0.0.0.0 --port 8080

Or run without adding a dependency:

pnpm dlx @itxtech/fd-server --host 0.0.0.0 --port 8080

In another terminal:

curl 'http://127.0.0.1:8080/info'
curl 'http://127.0.0.1:8080/decode?pn=MT29F4G08ABAEA&lang=eng'

Set Classic's server address to http://127.0.0.1:8080, without a path prefix. Defaults are Chinese responses, the selected controller group, 300 search results, and wildcard CORS; see Environment variables.

Legacy routes

  • /
  • /info
  • /decode?pn=...&lang=...
  • /decodeId?id=...&lang=...
  • /searchPn?pn=...&lang=...&limit=...
  • /searchId?id=...&lang=...&limit=...
  • /summary?pn=...&lang=...
  • /summaryId?id=...&lang=...

Cloudflare Workers deployment

The following commands use a repository checkout and require a Cloudflare account with Wrangler authentication. Wrangler is installed from the root development dependencies; see Worker prerequisites for installation and build permissions. The configuration is packages/fd-server/wrangler.jsonc:

{
  "name": "fdnext-fd-server",
  "main": "dist/worker.js",
  "compatibility_date": "2026-06-13",
  "compatibility_flags": ["nodejs_compat"],
  "workers_dev": true,
  "minify": true,
  "keep_vars": true,
  "build": {
    "command": "pnpm build",
    "watch_dir": [
      "../core/src",
      "../core/resources",
      "src"
    ]
  },
  "dev": {
    "port": 8080,
    "local_protocol": "http"
  }
}
  • main points to the Worker bundle generated by build.command, which runs pnpm build inside packages/fd-server.
  • watch_dir covers adapter and core sources/resources for local development.
  • nodejs_compat supports Node built-in references from bundled dependencies.
  • keep_vars preserves Dashboard variables across deployments.
  • workers_dev enables *.workers.dev; bind production domains in the Dashboard or configure route / routes.

Local development

From the repository root:

pnpm install --frozen-lockfile
pnpm fdserver:worker:dev

Wrangler builds before serving at http://127.0.0.1:8080. Use that root URL in the local Classic client.

Manual deployment

Inspect the Wrangler bundle, then deploy:

pnpm fdserver:worker:deploy:dry-run
pnpm fdserver:worker:deploy

Set Classic's server address to the returned root URL, such as https://fdnext-fd-server.<account>.workers.dev, or a bound domain such as https://fd.example.com. Legacy routes must be available directly at the root, including /decode and /decodeId.

Cloudflare Workers Builds

For Git-connected Dashboard deployment:

Setting Value
Root directory Empty or repository root
Build command pnpm install --frozen-lockfile && pnpm -C packages/fd-server build
Deploy command pnpm fdserver:worker:deploy
Non-production branch deploy command pnpm -C packages/fd-server exec wrangler versions upload --config wrangler.jsonc

Set build variable SKIP_DEPENDENCY_INSTALL=1 so the explicit pnpm command handles installation rather than another package manager selected by the platform.

Worker variables

Keep keep_vars: true and manage production variables in the Dashboard. For local development, use packages/fd-server/.dev.vars:

FD_SERVER_DEFAULT_LANG=chs
FD_SERVER_CONTROLLER_GROUP=selected
FD_SERVER_SEARCH_LIMIT=300
FDNEXT_CORS_ORIGINS=*
FD_SERVER_EXTRA_URLS='{"Try the new FlashMaster":"https://fm.itxtech.org"}'

Do not commit .dev.vars or .env. Variable meanings are in Environment variables. After deployment, run the smoke checks with the Worker URL.

Node.js development

From the repository root:

pnpm install
pnpm fdserver:dev

The default address is http://0.0.0.0:8080. Override it with CLI arguments:

pnpm fdserver:dev -- --host 127.0.0.1 --port 8081

Node.js production build

From the repository root:

pnpm install --frozen-lockfile
pnpm -C packages/fd-server build
pnpm -C packages/fd-server start

Or run the built entry with explicit arguments:

node packages/fd-server/dist/bin.js --host 0.0.0.0 --port 8080
CLI option Default Meaning
--host 0.0.0.0 Bind address
--port 8080 Listening port

Language, controller projection, and extra links are environment settings, not CLI options. For self-hosted production, use a reverse proxy for HTTPS.

Environment variables

FD_SERVER_DEFAULT_LANG

Default response language for missing or invalid request lang. Accepts chs or eng; empty/invalid configuration falls back to chs.

FD_SERVER_DEFAULT_LANG=chs

FD_SERVER_CONTROLLER_GROUP

Server-side controller projection for decode output; defaults to selected.

FD_SERVER_CONTROLLER_GROUP=selected
FD_SERVER_CONTROLLER_GROUP=all
FD_SERVER_CONTROLLER_GROUP=if:sata,if:nvme

The legacy API ignores client controllerGroup parameters and uses this setting.

FD_SERVER_SEARCH_LIMIT

Default and maximum result count for /searchPn and /searchId; defaults to 300. Client limit can only lower the cap.

FD_SERVER_SEARCH_LIMIT=300

FDNEXT_SEARCH_LIMIT is also supported; FD_SERVER_SEARCH_LIMIT takes precedence when both are supplied. Use a positive safe integer; invalid values fall back to 300. Raise the server cap if clients need more results.

FDNEXT_CORS_ORIGINS

Classic defaults to * when unset. An exact allowlist match echoes the origin with Vary: Origin; separate origins with commas, spaces, or newlines. CORS preflight returns 204 and echoes requested headers. See the shared CORS rules.

FD_SERVER_EXTRA_URLS

JSON object appended to data.url in /decode and /decodeId responses:

FD_SERVER_EXTRA_URLS='{"Try the new FlashMaster":"https://fm.itxtech.org"}'

Only nonempty labels and http:// / https:// URLs are accepted. Invalid JSON is ignored; a configured warning callback reports it (the Worker supplies one). Extra links do not appear in search or summary responses.

PM2 deployment

Build from the repository and start PM2:

pnpm install --frozen-lockfile
pnpm -C packages/fd-server build
pm2 start packages/fd-server/ecosystem.config.cjs

To inject extra links:

FD_SERVER_EXTRA_URLS='{"Try the new FlashMaster":"https://fm.itxtech.org"}' \
pm2 start packages/fd-server/ecosystem.config.cjs

Common operations:

pm2 status
pm2 logs fd-server
pm2 restart fd-server --update-env
pm2 save

systemd deployment

Example service unit (adjust installation paths for your server):

[Unit]
Description=fd-server FlashDetector compatibility API
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/fdnext
Environment=NODE_ENV=production
Environment=FD_SERVER_DEFAULT_LANG=chs
Environment=FD_SERVER_CONTROLLER_GROUP=selected
Environment="FD_SERVER_EXTRA_URLS={\"Try the new FlashMaster\":\"https://fm.itxtech.org\"}"
ExecStart=/usr/bin/node packages/fd-server/dist/bin.js --host 127.0.0.1 --port 8080
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

After saving the unit:

systemctl daemon-reload
systemctl enable --now fd-server
systemctl status fd-server
journalctl -u fd-server -f

If inline JSON requires different escaping in your environment, use EnvironmentFile with the systemd syntax for your distribution.

Reverse proxy

Bind fd-server to loopback and terminate HTTPS at nginx, Caddy, Apache, or another gateway. Minimal nginx example:

server {
    listen 443 ssl;
    server_name fd.example.com;

    ssl_certificate /etc/letsencrypt/live/fd.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/fd.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Configure Classic with https://fd.example.com. Add a path prefix only if the proxy strips it before forwarding; Classic expects legacy routes at the service root.

Smoke checks

curl 'http://127.0.0.1:8080/'
curl 'http://127.0.0.1:8080/info'
curl 'http://127.0.0.1:8080/decode?pn=MT29F4G08ABAEA&lang=chs'
curl 'http://127.0.0.1:8080/decodeId?id=2C64444BA900&lang=chs'
curl 'http://127.0.0.1:8080/searchPn?pn=MT29F4G08ABAEA&lang=eng&limit=5'
curl 'http://127.0.0.1:8080/searchId?id=2C64&lang=eng&limit=5'
  • / includes result: true, Unix-seconds time, and server: "fdnext-fd-server".
  • /info includes a nonempty info.fdb.controllers list.
  • /decode and /decodeId return legacy FlashInfo and FlashIdInfo fields respectively.
  • Modern routes such as /parts/decode return { "result": false, "message": "Not found" }.

Classic configuration

Point Classic to the local service root or HTTPS proxy/Worker root. The UI renders legacy fields, including extraInfo and ext keys; fd-server localizes them according to request lang.

Operations

  • Embedded core resources are used; custom resource directories are not supported.
  • Business errors use HTTP 200 with { "result": false, "message": "..." }, following FlashDetector behavior.
  • Use selected for a concise controller list and all when the complete set is needed.
  • Handle HTTPS, caching, access logs, and rate limits at the proxy or platform layer.

Source organization

  • handler.ts owns stable creation functions and public exports shared by Node and Worker consumers.
  • routes.ts adapts legacy paths, parameters, and responses.
  • legacy-serializer.ts converts fdnext results to FlashDetector field shapes.
  • config.ts and types.ts own configuration and public types. Core decoding, search, and indexes remain in @itxtech/fdnext-core.

Validation

See Validation (Chinese) for check selection and Manual deployment for Worker bundle inspection.