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
JavaScript
"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;
};