Some checks failed
farmcontrol/farmcontrol-scheduler/pipeline/head There was a failure building this commit
167 lines
4.3 KiB
JavaScript
167 lines
4.3 KiB
JavaScript
import mongoose from 'mongoose';
|
|
import { generateId } from '../../utils.js';
|
|
const { Schema } = mongoose;
|
|
|
|
const RENDER_DOCUMENT_TEMPLATE_CALL =
|
|
/fc\.renderDocumentTemplate\s*\(\s*(['"])([^'"]+)\1/g;
|
|
|
|
function extractRenderDocumentTemplateReferences(content) {
|
|
if (content == null || typeof content !== 'string' || content === '') {
|
|
return [];
|
|
}
|
|
|
|
const references = [];
|
|
const seen = new Set();
|
|
const regex = new RegExp(RENDER_DOCUMENT_TEMPLATE_CALL.source, 'g');
|
|
let match;
|
|
while ((match = regex.exec(content)) !== null) {
|
|
const reference = match[2]?.trim();
|
|
if (!reference || seen.has(reference)) {
|
|
continue;
|
|
}
|
|
seen.add(reference);
|
|
references.push(reference);
|
|
}
|
|
return references;
|
|
}
|
|
|
|
function objectIdsFromFilterValue(value) {
|
|
if (value == null) {
|
|
return [];
|
|
}
|
|
if (value instanceof mongoose.Types.ObjectId) {
|
|
return [value];
|
|
}
|
|
if (typeof value === 'string' && /^[a-f\d]{24}$/i.test(value)) {
|
|
return [new mongoose.Types.ObjectId(value)];
|
|
}
|
|
if (Array.isArray(value)) {
|
|
return value.flatMap(objectIdsFromFilterValue);
|
|
}
|
|
if (typeof value === 'object') {
|
|
if (Array.isArray(value.$in)) {
|
|
return objectIdsFromFilterValue(value.$in);
|
|
}
|
|
if (value._id != null) {
|
|
return objectIdsFromFilterValue(value._id);
|
|
}
|
|
}
|
|
return [];
|
|
}
|
|
|
|
const documentTemplateSchema = new Schema(
|
|
{
|
|
_reference: { type: String, default: () => generateId()() },
|
|
name: {
|
|
type: String,
|
|
required: true,
|
|
unique: true,
|
|
},
|
|
objectType: { type: String, required: false },
|
|
tags: [{ type: String }],
|
|
active: {
|
|
type: Boolean,
|
|
required: true,
|
|
default: true,
|
|
},
|
|
global: {
|
|
type: Boolean,
|
|
required: true,
|
|
default: false,
|
|
},
|
|
parent: {
|
|
type: Schema.Types.ObjectId,
|
|
ref: 'documentTemplate',
|
|
required: false,
|
|
},
|
|
documentSize: {
|
|
type: Schema.Types.ObjectId,
|
|
ref: 'documentSize',
|
|
required: true,
|
|
},
|
|
documentPrinters: [
|
|
{
|
|
type: Schema.Types.ObjectId,
|
|
ref: 'documentPrinter',
|
|
required: false,
|
|
},
|
|
],
|
|
referencedTemplates: [
|
|
{
|
|
type: Schema.Types.ObjectId,
|
|
ref: 'documentTemplate',
|
|
required: false,
|
|
},
|
|
],
|
|
content: {
|
|
type: String,
|
|
required: false,
|
|
default: '<Container></Container>',
|
|
},
|
|
testObject: {
|
|
type: Schema.Types.ObjectId,
|
|
refPath: 'objectType',
|
|
required: false,
|
|
},
|
|
},
|
|
{ timestamps: true }
|
|
);
|
|
|
|
documentTemplateSchema.index({ name: 'text', tags: 'text', objectType: 'text' });
|
|
|
|
// Add virtual id getter
|
|
documentTemplateSchema.virtual('id').get(function () {
|
|
return this._id;
|
|
});
|
|
|
|
// Configure JSON serialization to include virtuals
|
|
documentTemplateSchema.set('toJSON', { virtuals: true });
|
|
|
|
documentTemplateSchema.statics.recalculate = async function (documentTemplate, user) {
|
|
const documentTemplateId = documentTemplate?._id || documentTemplate;
|
|
if (!documentTemplateId) {
|
|
return;
|
|
}
|
|
|
|
const stillExists = await this.exists({ _id: documentTemplateId });
|
|
if (!stillExists) {
|
|
return;
|
|
}
|
|
|
|
const { getFilter } = await import('../../../utils.js');
|
|
const references = extractRenderDocumentTemplateReferences(documentTemplate?.content);
|
|
const referencedTemplateIds = [];
|
|
const seenIds = new Set();
|
|
|
|
for (const reference of references) {
|
|
const filter = await getFilter({ parent: reference }, ['parent'], true, this);
|
|
const ids = objectIdsFromFilterValue(filter.parent);
|
|
for (const id of ids) {
|
|
const idString = String(id);
|
|
if (!idString || seenIds.has(idString)) {
|
|
continue;
|
|
}
|
|
seenIds.add(idString);
|
|
referencedTemplateIds.push(id);
|
|
}
|
|
}
|
|
|
|
if (documentTemplate && typeof documentTemplate === 'object' && !documentTemplate._bsontype) {
|
|
documentTemplate.referencedTemplates = referencedTemplateIds.map((id) => ({
|
|
_id: String(id),
|
|
}));
|
|
}
|
|
|
|
const { editObject } = await import('../../database.js');
|
|
await editObject({
|
|
model: this,
|
|
id: documentTemplateId,
|
|
updateData: { referencedTemplates: referencedTemplateIds },
|
|
user,
|
|
populate: [{ path: 'referencedTemplates', strictPopulate: false }],
|
|
recalculate: false,
|
|
});
|
|
};
|
|
|
|
export const documentTemplateModel = mongoose.model('documentTemplate', documentTemplateSchema);
|