This commit is contained in:
seb
2026-11-01 03:33:14 +01:00
parent 5d6b31de15
commit cb30352b57
12 changed files with 25 additions and 902 deletions

View File

@@ -1,18 +1,16 @@
# syntax=docker/dockerfile:1 # syntax=docker/dockerfile:1
FROM debian:12-slim AS syslibs FROM debian:12-slim AS syslibs
RUN apt-get update && apt-get install -y --no-install-recommends \ RUN apt-get update && apt-get install -y --no-install-recommends \
libatomic1 libuuid1 libfontconfig1 libfribidi0 \ libatomic1 libuuid1 \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
FROM gcr.io/distroless/cc-debian12 FROM gcr.io/distroless/cc-debian12
WORKDIR /app WORKDIR /app
# Shared dynamic libraries needed by Node.js SEA and native addons (canvas, better-sqlite3) # Shared dynamic libraries needed by Node.js SEA and native addons (better-sqlite3)
COPY --from=syslibs /usr/lib/x86_64-linux-gnu/libatomic.so* /usr/lib/x86_64-linux-gnu/ COPY --from=syslibs /usr/lib/x86_64-linux-gnu/libatomic.so* /usr/lib/x86_64-linux-gnu/
COPY --from=syslibs /usr/lib/x86_64-linux-gnu/libuuid.so* /usr/lib/x86_64-linux-gnu/ COPY --from=syslibs /usr/lib/x86_64-linux-gnu/libuuid.so* /usr/lib/x86_64-linux-gnu/
COPY --from=syslibs /usr/lib/x86_64-linux-gnu/libfontconfig.so* /usr/lib/x86_64-linux-gnu/
COPY --from=syslibs /usr/lib/x86_64-linux-gnu/libfribidi.so* /usr/lib/x86_64-linux-gnu/
# Set production defaults: port 4208 # Set production defaults: port 4208
ENV RUNNING_IN_DOCKER=true \ ENV RUNNING_IN_DOCKER=true \

View File

@@ -362,7 +362,6 @@ Clients subscribe via [`GET /events`](routes/events.md) (`text/event-stream`). A
| `modelconversation-<id>` | `POST /modelconversation/{id}/message` | | `modelconversation-<id>` | `POST /modelconversation/{id}/message` |
| `order` | `DELETE /order/{id}/file/{fileId}`, `POST /order/{id}/pdf`, `DELETE /shipment/{id}`, `PATCH /shipment/{id}`, `DELETE /shipment/{id}/file/{fileId}` | | `order` | `DELETE /order/{id}/file/{fileId}`, `POST /order/{id}/pdf`, `DELETE /shipment/{id}`, `PATCH /shipment/{id}`, `DELETE /shipment/{id}/file/{fileId}` |
| `printer` | `POST /printer`, `PUT /printer/order`, `DELETE /printer/{id}`, `PATCH /printer/{id}`, `PUT /printer/{id}` | | `printer` | `POST /printer`, `PUT /printer/order`, `DELETE /printer/{id}`, `PATCH /printer/{id}`, `PUT /printer/{id}` |
| `printerjob` | `POST /printerjob`, `POST /printerjob/cancel-all`, `DELETE /printerjob/{id}`, `POST /printerjob/{id}/cancel`, `POST /zpljob` |
| `propertyname` | `POST /propertyname`, `PUT /propertyname/order`, `DELETE /propertyname/{id}`, `PATCH /propertyname/{id}` | | `propertyname` | `POST /propertyname`, `PUT /propertyname/order`, `DELETE /propertyname/{id}`, `PATCH /propertyname/{id}` |
| `quote` | `DELETE /quote/{id}/file/{fileId}`, `POST /quote/{id}/pdf` | | `quote` | `DELETE /quote/{id}/file/{fileId}`, `POST /quote/{id}/pdf` |
| `shipment` | `DELETE /shipment/{id}`, `PATCH /shipment/{id}`, `DELETE /shipment/{id}/file/{fileId}`, `POST /shipment/{id}/pdf` | | `shipment` | `DELETE /shipment/{id}`, `PATCH /shipment/{id}`, `DELETE /shipment/{id}/file/{fileId}`, `POST /shipment/{id}/pdf` |

View File

@@ -48,7 +48,6 @@ emits `{ sender, brandId }`.
| `printer` | `{}` | `POST /printer`, `PUT /printer/{id}`, `PATCH /printer/{id}`, `DELETE /printer/{id}` | | `printer` | `{}` | `POST /printer`, `PUT /printer/{id}`, `PATCH /printer/{id}`, `DELETE /printer/{id}` |
| `printeragent` | `{}` | `PUT /printeragent`, `PATCH /printeragent/{id}`, `DELETE /printeragent/{id}`, printer agent connect/disconnect/state | | `printeragent` | `{}` | `PUT /printeragent`, `PATCH /printeragent/{id}`, `DELETE /printeragent/{id}`, printer agent connect/disconnect/state |
| `agentprinter` | `{ printers }` or `{}` | `PATCH /agentprinter/{id}`, `PUT /agentprinter/order`, `DELETE /agentprinter/{id}`, agent state updates / printer discovery | | `agentprinter` | `{ printers }` or `{}` | `PATCH /agentprinter/{id}`, `PUT /agentprinter/order`, `DELETE /agentprinter/{id}`, agent state updates / printer discovery |
| `printerjob` | `{ job }` or `{ jobId, state }` | `POST /zpljob`, `POST /printerjob`, `POST /printerjob/{id}/cancel`, `DELETE /printerjob/{id}`, agent job state updates |
| `warehouse` | `{}` | `POST /warehouse`, `PUT /warehouse/{id}`, `PATCH /warehouse/{id}`, `DELETE /warehouse/{id}` | | `warehouse` | `{}` | `POST /warehouse`, `PUT /warehouse/{id}`, `PATCH /warehouse/{id}`, `DELETE /warehouse/{id}` |
| `supplier` | `{}` | `POST /supplier`, `PATCH /supplier/{id}`, `DELETE /supplier/{id}` | | `supplier` | `{}` | `POST /supplier`, `PATCH /supplier/{id}`, `DELETE /supplier/{id}` |
| `vfs` | `{}` | VFS uploads and filesystem mutations such as `POST /vfs/upload`, `POST /vfs/mkdir`, `POST /vfs/rename`, `PUT /vfs/{*path}`, `DELETE /vfs/{*path}` | | `vfs` | `{}` | VFS uploads and filesystem mutations such as `POST /vfs/upload`, `POST /vfs/mkdir`, `POST /vfs/rename`, `PUT /vfs/{*path}`, `DELETE /vfs/{*path}` |

View File

@@ -22,10 +22,6 @@ Creates a new print job for an agent printer. Notifies the agent in real time.
} }
``` ```
## Signals
On success, emits SSE signal: `printerjob` (see [`GET /events`](../events.md)).
## Response `201` ## Response `201`
Printer job created Printer job created

View File

@@ -14,10 +14,6 @@ event to the connected printer agent before deletion.
|-------|----------|------|-------------| |-------|----------|------|-------------|
| `id` | yes | integer | | | `id` | yes | integer | |
## Signals
On success, emits SSE signal: `printerjob` (see [`GET /events`](../events.md)).
## Response `200` ## Response `200`
Job cancelled and deleted Job cancelled and deleted

View File

@@ -12,10 +12,6 @@ Marks a print job as cancelled and notifies the connected agent in real time.
|-------|----------|------|-------------| |-------|----------|------|-------------|
| `id` | yes | integer | | | `id` | yes | integer | |
## Signals
On success, emits SSE signal: `printerjob` (see [`GET /events`](../events.md)).
## Response `200` ## Response `200`
Printer job cancelled Printer job cancelled

View File

@@ -20,10 +20,6 @@ Notifies connected agents in real time.
} }
``` ```
## Signals
On success, emits SSE signal: `printerjob` (see [`GET /events`](../events.md)).
## Response `200` ## Response `200`
All matching jobs cancelled All matching jobs cancelled

View File

@@ -24,10 +24,6 @@ is automatically applied. The connected printer agent receives an immediate real
} }
``` ```
## Signals
On success, emits SSE signal: `printerjob` (see [`GET /events`](../events.md)).
## Response `201` ## Response `201`
Print job created Print job created

874
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -43,7 +43,7 @@
"pdfconvert-wasm": "^0.3.0", "pdfconvert-wasm": "^0.3.0",
"pdfkit": "^0.20.2", "pdfkit": "^0.20.2",
"react": "^19.3.1", "react": "^19.3.1",
"react-canvas-label-editor": "github:sebseb7/react-canvas-label-editor", "react-canvas-label-editor": "github:sebseb7/react-canvas-label-editor#v19.0.0",
"selfsigned": "^5.5.0", "selfsigned": "^5.5.0",
"skelehash-wasm": "^0.1.1", "skelehash-wasm": "^0.1.1",
"swagger-ui-dist": "^5.33.3", "swagger-ui-dist": "^5.33.3",
@@ -57,8 +57,7 @@
"swagger-jsdoc": "^6.3.0" "swagger-jsdoc": "^6.3.0"
}, },
"allowScripts": { "allowScripts": {
"github:sebseb7/react-canvas-label-editor#7f0e31b66ff22da011e872b201017398b14e9dd9": true, "react-canvas-label-editor@19.0.0": true,
"canvas@3.2.3": true,
"better-sqlite3@13.0.3": true "better-sqlite3@13.0.3": true
}, },
"overrides": { "overrides": {

View File

@@ -56,21 +56,13 @@ function getProjectRoot() {
? JSON.parse(fs.readFileSync(nativeMapFile, 'utf8')) ? JSON.parse(fs.readFileSync(nativeMapFile, 'utf8'))
: {}; : {};
// Redirect native .node loading to distDir and preload libvips from distDir if present // Redirect native .node loading to distDir if present
const origDlopen = process.dlopen; const origDlopen = process.dlopen;
process.dlopen = function (mod, filename, flags) { process.dlopen = function (mod, filename, flags) {
const relFromRuntime = path.relative(runtimeDir, filename); const relFromRuntime = path.relative(runtimeDir, filename);
const mappedName = nativeNodes[relFromRuntime] || path.basename(filename); const mappedName = nativeNodes[relFromRuntime] || path.basename(filename);
const distCandidate = path.join(distDir, mappedName); const distCandidate = path.join(distDir, mappedName);
const target = fs.existsSync(distCandidate) ? distCandidate : filename; const target = fs.existsSync(distCandidate) ? distCandidate : filename;
if (mappedName.startsWith('sharp-')) {
const vipsPath = path.join(distDir, 'libvips-cpp.so.8.18.7');
if (fs.existsSync(vipsPath)) {
try {
origDlopen.call(process, { exports: {} }, vipsPath, os.constants.dlopen.RTLD_NOW | os.constants.dlopen.RTLD_GLOBAL);
} catch {}
}
}
return flags !== undefined ? origDlopen.call(process, mod, target, flags) : origDlopen.call(process, mod, target); return flags !== undefined ? origDlopen.call(process, mod, target, flags) : origDlopen.call(process, mod, target);
}; };

View File

@@ -1,4 +1,4 @@
import { createCanvas, loadImage } from 'canvas'; import { optimizeImage } from 'wasm-image-optimization';
/** /**
* Converts a PNG image buffer into Zebra ZPL II Graphic Field (^GFA) format. * Converts a PNG image buffer into Zebra ZPL II Graphic Field (^GFA) format.
@@ -10,12 +10,8 @@ import { createCanvas, loadImage } from 'canvas';
* @returns {Promise<string>} Full ZPL string ready to send to a Zebra printer. * @returns {Promise<string>} Full ZPL string ready to send to a Zebra printer.
*/ */
export async function pngToZpl(pngBuffer, quantity = 1) { export async function pngToZpl(pngBuffer, quantity = 1) {
const img = await loadImage(pngBuffer); const raw = await optimizeImage({ image: pngBuffer, format: 'raw' });
const canvas = createCanvas(img.width, img.height); const { width: w, height: h, data } = raw;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const imgData = ctx.getImageData(0, 0, img.width, img.height);
const { data, width: w, height: h } = imgData;
const bytesPerRow = Math.ceil(w / 8); const bytesPerRow = Math.ceil(w / 8);
const totalBytes = bytesPerRow * h; const totalBytes = bytesPerRow * h;