Initial release v1.0.0 — Nextcloud Collabora Node-RED sidecar
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
'use strict';
|
||||
|
||||
const FormData = require('form-data');
|
||||
const { requestStream } = require('./http-client');
|
||||
|
||||
function collaboraBase(config) {
|
||||
return (config.collaboraUrl || '').replace(/\/$/, '');
|
||||
}
|
||||
|
||||
function tlsOptions(config) {
|
||||
return config.verifyTls !== false && config.verifyTls !== 'false';
|
||||
}
|
||||
|
||||
function buildMultipart(fields) {
|
||||
const form = new FormData();
|
||||
for (const field of fields) {
|
||||
if (field.buffer) {
|
||||
form.append(field.name, field.buffer, {
|
||||
filename: field.filename || 'document.bin',
|
||||
contentType: field.contentType || 'application/octet-stream'
|
||||
});
|
||||
} else if (field.value !== undefined) {
|
||||
form.append(field.name, String(field.value));
|
||||
}
|
||||
}
|
||||
return form;
|
||||
}
|
||||
|
||||
async function postMultipart(config, endpoint, fields) {
|
||||
const form = buildMultipart(fields);
|
||||
const url = `${collaboraBase(config)}${endpoint}`;
|
||||
|
||||
const res = await requestStream(
|
||||
{
|
||||
url,
|
||||
method: 'POST',
|
||||
headers: form.getHeaders(),
|
||||
rejectUnauthorized: tlsOptions(config)
|
||||
},
|
||||
(req) => form.pipe(req)
|
||||
);
|
||||
|
||||
if (res.statusCode < 200 || res.statusCode >= 300) {
|
||||
const snippet = res.body.toString('utf8').slice(0, 300);
|
||||
throw new Error(`Collabora ${endpoint} misslyckades (${res.statusCode}): ${snippet}`);
|
||||
}
|
||||
|
||||
if (!res.body || res.body.length === 0) {
|
||||
throw new Error(`Collabora ${endpoint} returnerade tomt svar — kontrollera intern URL och post_allow`);
|
||||
}
|
||||
|
||||
return {
|
||||
buffer: res.body,
|
||||
contentType: res.headers['content-type'],
|
||||
statusCode: res.statusCode
|
||||
};
|
||||
}
|
||||
|
||||
async function convertTo(config, { buffer, filename, format, extraFields = [] }) {
|
||||
const fmt = String(format || 'pdf').toLowerCase();
|
||||
const fields = [
|
||||
{ name: 'data', buffer, filename: filename || 'document.bin' },
|
||||
...extraFields
|
||||
];
|
||||
|
||||
try {
|
||||
return await postMultipart(config, `/cool/convert-to/${fmt}`, fields);
|
||||
} catch (err) {
|
||||
fields.push({ name: 'format', value: fmt });
|
||||
return postMultipart(config, '/cool/convert-to', fields);
|
||||
}
|
||||
}
|
||||
|
||||
async function extractStructure(config, { buffer, filename, filter }) {
|
||||
const fields = [{ name: 'data', buffer, filename: filename || 'document.bin' }];
|
||||
if (filter) {
|
||||
fields.push({ name: 'filter', value: typeof filter === 'string' ? filter : JSON.stringify(filter) });
|
||||
}
|
||||
const res = await postMultipart(config, '/cool/extract-document-structure', fields);
|
||||
try {
|
||||
return JSON.parse(res.buffer.toString('utf8'));
|
||||
} catch {
|
||||
return { raw: res.buffer.toString('utf8') };
|
||||
}
|
||||
}
|
||||
|
||||
async function transformStructure(config, { buffer, filename, transform }) {
|
||||
const fields = [
|
||||
{ name: 'data', buffer, filename: filename || 'document.bin' },
|
||||
{ name: 'transform', value: typeof transform === 'string' ? transform : JSON.stringify(transform) }
|
||||
];
|
||||
const res = await postMultipart(config, '/cool/transform-document-structure', fields);
|
||||
return {
|
||||
buffer: res.buffer,
|
||||
contentType: res.contentType
|
||||
};
|
||||
}
|
||||
|
||||
async function getCapabilities(config) {
|
||||
const url = `${collaboraBase(config)}/hosting/capabilities`;
|
||||
const { requestBuffer } = require('./http-client');
|
||||
const res = await requestBuffer({
|
||||
url,
|
||||
method: 'GET',
|
||||
rejectUnauthorized: tlsOptions(config)
|
||||
});
|
||||
if (res.statusCode < 200 || res.statusCode >= 300) {
|
||||
throw new Error(`Capabilities misslyckades (${res.statusCode})`);
|
||||
}
|
||||
return JSON.parse(res.body.toString('utf8'));
|
||||
}
|
||||
|
||||
async function getDiscovery(config) {
|
||||
const url = `${collaboraBase(config)}/hosting/discovery`;
|
||||
const { requestBuffer } = require('./http-client');
|
||||
const res = await requestBuffer({
|
||||
url,
|
||||
method: 'GET',
|
||||
rejectUnauthorized: tlsOptions(config)
|
||||
});
|
||||
if (res.statusCode < 200 || res.statusCode >= 300) {
|
||||
throw new Error(`Discovery misslyckades (${res.statusCode})`);
|
||||
}
|
||||
return res.body.toString('utf8');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
convertTo,
|
||||
extractStructure,
|
||||
transformStructure,
|
||||
getCapabilities,
|
||||
getDiscovery,
|
||||
postMultipart
|
||||
};
|
||||
Reference in New Issue
Block a user