UNPKG

gatsby-source-personio-xml

Version:

Gatsby source plugin to use a Personio XML feed as a data source

142 lines (141 loc) 4.72 kB
"use strict"; var _xpath = require("xpath"); var _xmldom = require("@xmldom/xmldom"); var _axios = _interopRequireDefault(require("axios")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } exports.createSchemaCustomization = ({ actions: { createTypes } }) => { createTypes(` type PersonioPosition implements Node { id: ID! positionId: Int! subcompany: String office: PersonioOffice @link(from: "office.name" by: "name") department: PersonioDepartment @link(from: "department.name" by: "name") recruitingCategory: String name: String! employmentType: String seniority: String schedule: String yearsOfExperience: String jobDescriptions: [JobDescription] } type JobDescription { name: String value: String } type PersonioDepartment implements Node { id: ID! name: String! positions: [PersonioPosition] @link(by: "positionId") } type PersonioOffice implements Node { id: ID! name: String! positions: [PersonioPosition] @link(by: "positionId") } `); }; exports.sourceNodes = async (props, { url, cusomizeXmlMapping, customizeNodeMapping }) => { const { actions: { createNode }, createContentDigest, createNodeId } = props; if (!url) { throw new Error('No Personio XML URL defined'); } console.info(`Fetching Personio XML…`); await _axios.default.get(url).then(response => { console.info(`Received Personio XML`); const data = readJobsFromXml(response.data, cusomizeXmlMapping); data.forEach(item => { createNode({ id: createNodeId(`personio-department-${item.department}`), name: item.department, positions: data.filter(i => i.department === item.department).map(i => i.id), parent: null, children: [], internal: { type: 'PersonioDepartment', contentDigest: createContentDigest(item.department) } }); createNode({ id: createNodeId(`personio-office-${item.office}`), name: item.office, positions: data.filter(i => i.office === item.office).map(i => i.id), parent: null, children: [], internal: { type: 'PersonioOffice', contentDigest: createContentDigest(item.office) } }); const newNode = { id: createNodeId(`personio-position-${item.id}`), positionId: item.id, subcompany: item.subcompany, office: { name: item.office }, department: { name: item.department }, recruitingCategory: item.recruitingCategory, name: item.name, employmentType: item.employmentType, seniority: item.seniority, schedule: item.schedule, yearsOfExperience: item.yearsOfExperience, jobDescriptions: item.jobDescriptions, parent: null, children: [], internal: { type: 'PersonioPosition', content: JSON.stringify(item), contentDigest: createContentDigest(item) } }; const convertedNode = customizeNodeMapping?.(newNode, item) ?? newNode; createNode(convertedNode); }); }).catch(() => console.error(`Fetching the Personio XML failed`)); return; }; const readJobsFromXml = (xml, cusomizeXmlMapping) => { const doc = new _xmldom.DOMParser().parseFromString(xml, 'application/xml'); return (0, _xpath.select)('//position', doc).map(node => { const newNode = { id: (0, _xpath.select)('number(id)', node), subcompany: optional((0, _xpath.select)('string(subcompany)', node)), office: (0, _xpath.select)('string(office)', node), department: (0, _xpath.select)('string(department)', node), recruitingCategory: (0, _xpath.select)('string(recruitingCategory)', node), name: (0, _xpath.select)('string(name)', node), employmentType: optional((0, _xpath.select)('string(employmentType)', node)), seniority: optional((0, _xpath.select)('string(seniority)', node)), schedule: optional((0, _xpath.select)('string(schedule)', node)), yearsOfExperience: optional((0, _xpath.select)('string(yearsOfExperience)', node)), jobDescriptions: (0, _xpath.select)(`jobDescriptions/jobDescription`, node).map(jobDescription => { return { name: (0, _xpath.select)('string(name)', jobDescription), value: (0, _xpath.select)('string(value)', jobDescription) }; }) }; return cusomizeXmlMapping?.(newNode, node) ?? newNode; }); }; const optional = value => { return !!value ? value : null; };