@websolutespa/payload-plugin-bowl
Version:
Bowl PayloadCms plugin of the BOM Repository
249 lines (248 loc) • 8.57 kB
JavaScript
import { bulkWrite, IBulkAction } from '@websolutespa/payload-utils/server';
export const TASK_NAME = 'bowlStaticTask';
export const QUEUE_NAME = 'bowlStaticQueue';
export const USE_EXPIRE_DATE = false;
export const TASK_OUTPUT_SCHEMA = [
{
name: 'inserted',
type: 'number',
required: true
},
{
name: 'updated',
type: 'number',
required: true
},
{
name: 'deleted',
type: 'number',
required: true
}
];
export const staticCollections = [];
function mapItems(items, map) {
if (typeof map === 'function') {
items = items.map((x)=>map(x));
} else if (typeof map === 'object') {
items = items.map((x)=>{
const item = {};
Object.entries(x).forEach(([k, v])=>{
item[map[k] || k] = v;
});
return item;
});
}
return items;
}
export async function seedStatic(payload) {
const now = new Date();
for (const collection of payload.config.collections){
if (collection.custom.type === 'static') {
const slug = collection.slug;
try {
let shouldSeed = true;
const findResult = await payload.find({
collection: slug,
limit: 1,
depth: 0,
overrideAccess: true
});
if (findResult.totalDocs > 0) {
if (USE_EXPIRE_DATE) {
const createdAt = findResult.docs[0].createdAt;
const duration = collection.custom.duration || 24 * 60 * 60;
let expireAt;
if (createdAt) {
expireAt = new Date();
expireAt.setTime(new Date(createdAt).getTime() + duration * 1000);
} else {
expireAt = now;
}
if (now.getTime() < expireAt.getTime()) {
payload.logger.info(`[Bowl] seedStatic '${slug}' already seeded`);
shouldSeed = false;
} else {
// bulk delete
await payload.delete({
collection: slug,
where: {
id: {
not_in: [
'not_exhistent_id'
]
}
}
});
payload.logger.info(`[Bowl] seedStatic '${slug}' cleared`);
}
} else {
shouldSeed = false;
}
}
if (shouldSeed) {
const src = collection.custom.src;
const response = await fetch(src);
if (response.ok) {
const data = await response.json();
const items = Array.isArray(data) ? data : data.items;
if (items && Array.isArray(items)) {
const mappedItems = mapItems(items);
// bulk insert
const createdAt = now.toISOString();
const records = mappedItems.map((item)=>({
action: IBulkAction.Insert,
item: {
...item,
createdAt,
updatedAt: createdAt
}
}));
const bulkWriteResults = await bulkWrite(payload, slug, records);
const insertedCount = bulkWriteResults?.insertedCount || 0;
if (items.length !== insertedCount) {
payload.logger.info(`[Bowl] seedStatic '${slug}' (${insertedCount})`);
}
} else {
payload.logger.info(`[Bowl] seedStatic '${slug}' records not found at '${src}'`);
}
}
}
} catch (error) {
console.log(error);
payload.logger.error(`[Bowl] seedStatic '${slug}'`, error);
}
}
}
}
export function getStaticTaskHandler(props) {
return async ({ req })=>{
try {
const { payload } = req;
await seedStatic(payload);
/*
const response = await fetch(`${uri}/api/v2/statements`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({
statement: `
SELECT
employee_email,
employee_id,
employee_name,
employee_first_name,
employee_surname,
employee_function,
department,
site,
reports_to,
manager_id,
manager_email,
started_on,
job_title,
curated_at
FROM
ANALYTICS.HUMAN_RESOURCES.REP__WEBSOLUTE_ORGCHART`,
}),
})
*/ return {
state: 'succeeded',
output: {
inserted: 0,
updated: 0,
deleted: 0
}
};
} catch (error) {
return {
state: 'failed',
errorMessage: 'message' in error && typeof error.message === 'string' ? error.message : String(error)
};
}
};
}
export async function enqueueTask({ payload }) {
await payload.jobs.queue({
queue: QUEUE_NAME,
task: TASK_NAME,
input: {}
});
}
export function configureStaticJobs(sourceConfig, cron = '* 0 0 * * *' // daily at midnight
) {
const staticTaskHandler = getStaticTaskHandler(sourceConfig);
const task = {
slug: TASK_NAME,
retries: 100,
outputSchema: TASK_OUTPUT_SCHEMA,
handler: async (args)=>{
const req = args.req;
const payload = req.payload;
const taskHandlerResult = await staticTaskHandler({
req
});
await enqueueTask({
payload
});
return taskHandlerResult;
}
};
const targetConfig = {
...sourceConfig,
jobs: {
...sourceConfig.jobs,
tasks: [
...sourceConfig.jobs?.tasks || [],
task
],
autoRun: async (payload)=>{
const cronConfigs = [];
const autoRun = sourceConfig.jobs?.autoRun;
if (typeof autoRun === 'function') {
cronConfigs.push(...await autoRun(payload));
} else if (Array.isArray(autoRun)) {
cronConfigs.push(...autoRun);
}
const cronConfig = {
cron,
queue: QUEUE_NAME
};
cronConfigs.push(cronConfig);
return cronConfigs;
}
},
onInit: async (payload)=>{
if (typeof sourceConfig.onInit === 'function') {
await sourceConfig.onInit(payload);
}
const pendingJobs = await payload.count({
collection: 'payload-jobs',
where: {
and: [
{
queue: {
equals: QUEUE_NAME
}
},
{
completedAt: {
equals: null
}
}
]
}
});
if (pendingJobs.totalDocs === 0) {
enqueueTask({
payload
});
}
await seedStatic(payload);
}
};
return targetConfig;
}
//# sourceMappingURL=static.service.js.map