farmcontrol-server/src/objectid.js
Tom Butcher 2522e2f9ce
Some checks failed
farmcontrol/farmcontrol-server/pipeline/head There was a failure building this commit
Update configuration and introduce object ID handling utilities
- Changed the API URL in both `config.json` and `src/config.js` for the development environment.
- Added a new `objectid.js` file containing utility functions for handling object IDs, including `stringifyIds` and `refId`.
- Updated the `PrinterDatabase`, `PrinterClient`, and `PrinterManager` classes to utilize the new object ID handling functions, ensuring consistent ID management across the application.
- Enhanced the `SocketClient` to incorporate a custom parser for handling string IDs in socket communications.
2026-11-07 18:53:01 +00:00

99 lines
3.2 KiB
JavaScript

function bytesOf(value) {
if (value == null) return null;
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {
return value.length === 12 ? value : null;
}
if (value instanceof Uint8Array) {
return value.byteLength === 12 ? Buffer.from(value) : null;
}
if (
value &&
value.type === 'Buffer' &&
Array.isArray(value.data) &&
value.data.length === 12
) {
return Buffer.from(value.data);
}
if (typeof value !== 'object' || Array.isArray(value) || value instanceof Date) {
return null;
}
const keys = Object.keys(value);
if (keys.length !== 12) return null;
const bytes = Buffer.alloc(12);
for (let index = 0; index < 12; index += 1) {
if (!Object.prototype.hasOwnProperty.call(value, index)) return null;
const byte = Number(value[index]);
if (!Number.isInteger(byte) || byte < 0 || byte > 255) return null;
bytes[index] = byte;
}
return bytes;
}
const PURE_REF_KEYS = new Set(['_id', 'id', 'buffer', '$oid']);
function isPureRef(value) {
if (value == null || typeof value !== 'object') return false;
if (typeof value.toHexString === 'function') return true;
if (Array.isArray(value) || value instanceof Date) return false;
const keys = Object.keys(value);
return keys.length > 0 && keys.every(key => PURE_REF_KEYS.has(key)) && refId(value) != null;
}
function isBinaryPayload(value) {
if (value == null || typeof value !== 'object') return false;
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) return true;
if (value instanceof Uint8Array || value instanceof ArrayBuffer) return true;
const name = value.constructor?.name;
return name === 'Blob' || name === 'File';
}
// Object ids are always hex strings on the wire. File buffers are left alone.
export function stringifyIds(value) {
if (value == null) return value;
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
return value;
}
if (typeof value.toHexString === 'function') return value.toHexString();
if (value instanceof Date || typeof value === 'function') return value;
if (isBinaryPayload(value)) return value;
if (Array.isArray(value)) return value.map(item => stringifyIds(item));
if (typeof value === 'object') {
if (isPureRef(value)) {
const id = refId(value);
if (typeof id === 'string') return id;
}
const copy = {};
for (const [key, child] of Object.entries(value)) {
copy[key] = stringifyIds(child);
}
return copy;
}
return value;
}
export function refId(value) {
if (value == null || value === '') return null;
if (typeof value === 'string') return value;
if (typeof value === 'object' && typeof value.toHexString === 'function') {
return value.toHexString();
}
if (typeof value !== 'object' || Array.isArray(value) || value instanceof Date) {
return null;
}
if (typeof value.$oid === 'string') return refId(value.$oid);
const keys = Object.keys(value);
if (
keys.length > 0 &&
keys.every(key => key === 'buffer' || key === 'id' || key === 'type' || key === 'data')
) {
const bytes = bytesOf(value.buffer) || bytesOf(value.id) || bytesOf(value);
if (bytes) return bytes.toString('hex');
}
if (value._id != null) return refId(value._id);
return null;
}