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
FROM debian:12-slim AS syslibs
RUN apt-get update && apt-get install -y --no-install-recommends \
libatomic1 libuuid1 libfontconfig1 libfribidi0 \
libatomic1 libuuid1 \
&& rm -rf /var/lib/apt/lists/*
FROM gcr.io/distroless/cc-debian12
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/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
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` |
| `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}` |
| `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}` |
| `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` |

View File

@@ -48,7 +48,6 @@ emits `{ sender, brandId }`.
| `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 |
| `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}` |
| `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}` |

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`
Printer job created

View File

@@ -14,10 +14,6 @@ event to the connected printer agent before deletion.
|-------|----------|------|-------------|
| `id` | yes | integer | |
## Signals
On success, emits SSE signal: `printerjob` (see [`GET /events`](../events.md)).
## Response `200`
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 | |
## Signals
On success, emits SSE signal: `printerjob` (see [`GET /events`](../events.md)).
## Response `200`
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`
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`
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",
"pdfkit": "^0.20.2",
"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",
"skelehash-wasm": "^0.1.1",
"swagger-ui-dist": "^5.33.3",
@@ -57,8 +57,7 @@
"swagger-jsdoc": "^6.3.0"
},
"allowScripts": {
"github:sebseb7/react-canvas-label-editor#7f0e31b66ff22da011e872b201017398b14e9dd9": true,
"canvas@3.2.3": true,
"react-canvas-label-editor@19.0.0": true,
"better-sqlite3@13.0.3": true
},
"overrides": {

View File

@@ -56,21 +56,13 @@ function getProjectRoot() {
? 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;
process.dlopen = function (mod, filename, flags) {
const relFromRuntime = path.relative(runtimeDir, filename);
const mappedName = nativeNodes[relFromRuntime] || path.basename(filename);
const distCandidate = path.join(distDir, mappedName);
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);
};

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.
@@ -10,12 +10,8 @@ import { createCanvas, loadImage } from 'canvas';
* @returns {Promise<string>} Full ZPL string ready to send to a Zebra printer.
*/
export async function pngToZpl(pngBuffer, quantity = 1) {
const img = await loadImage(pngBuffer);
const canvas = createCanvas(img.width, img.height);
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 raw = await optimizeImage({ image: pngBuffer, format: 'raw' });
const { width: w, height: h, data } = raw;
const bytesPerRow = Math.ceil(w / 8);
const totalBytes = bytesPerRow * h;