sfcc-dts
Version:
> High quality Salesforce Commerce Cloud type definitions. A dw-api-types "done right"
252 lines (247 loc) • 9.13 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateConstants = exports.generateCustomTypes = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const picocolors_1 = __importDefault(require("picocolors"));
const prettier_1 = __importDefault(require("prettier"));
const xml2js_1 = __importDefault(require("xml2js"));
async function generateCustomTypes(extensionsfolder) {
let typeExtensions = [];
let folder = fs_1.default.readdirSync(extensionsfolder).filter(i => !fs_1.default.lstatSync(path_1.default.join(extensionsfolder, i)).isDirectory() && i.endsWith('.xml'));
for (let j = 0; j < folder.length; j++) {
let extensions = path_1.default.join(extensionsfolder, folder[j]);
typeExtensions = typeExtensions.concat(await parseMeta(extensions));
}
typeExtensions = typeExtensions.filter(te => te.typeid && te.attributedefinitions && te.attributedefinitions.length > 0).sort((a, b) => a.typeid.localeCompare(b.typeid));
let uniquetypes = {};
typeExtensions.forEach(ts => {
if (!uniquetypes[ts.typeid]) {
uniquetypes[ts.typeid] = ts;
}
else {
uniquetypes[ts.typeid].attributedefinitions = uniquetypes[ts.typeid].attributedefinitions.concat(ts.attributedefinitions);
}
});
let attrspath = path_1.default.join(__dirname, '../@types/sfcc/attrs.txt');
console.log('path is ' + attrspath);
let customObjList = new Set(fs_1.default.readFileSync(attrspath, 'utf8').split('\n'));
let customattrsrc = Object.keys(uniquetypes).map((k) => {
let i = uniquetypes[k];
let typename = i.typeid;
customObjList.delete(typename);
i.attributedefinitions = i.attributedefinitions.sort((a, b) => a.attributeid.localeCompare(b.attributeid));
return `
/**
* Custom attributes for ${typename} object.
*/
declare class ${typename}CustomAttributes {
${i.attributedefinitions.map(at => mapAttribute(at)).join('\n')}
}`;
}).join('\n');
customattrsrc += Array.from(customObjList).map((typename) => {
return `
/**
* Custom attributes for ${typename} object.
*/
declare class ${typename}CustomAttributes {
/**
* Returns the custom attribute with this name. Throws an exception if attribute is not defined
*/
[name: string]: any;
}`;
}).join('\n');
let out = customattrsrc;
let outpath = path_1.default.join('@types/dw', "attrs.d.ts");
let prettierconfig = {};
if (fs_1.default.existsSync('.prettierrc')) {
try {
prettierconfig = JSON.parse(fs_1.default.readFileSync('.prettierrc', 'utf8'));
}
catch (e) {
console.log(picocolors_1.default.red(`Unable to parse local .prettierrc: ${e}`));
}
}
prettierconfig.parser = "typescript";
prettierconfig.proseWrap = 'always';
try {
out = prettier_1.default.format(customattrsrc, prettierconfig);
}
catch (e) {
console.error(picocolors_1.default.red(`Prettier format failed, check generated file at ${outpath}\n${e}`));
}
fs_1.default.writeFileSync(outpath, out);
}
exports.generateCustomTypes = generateCustomTypes;
function attributeConstant(at) {
return `${at.attributeid} : '${at.attributeid}'
`;
}
async function generateConstants(extensions, dest) {
let typeExtensions = await parseMeta(extensions);
let customattrsrc = Array.from(typeExtensions).filter(i => i.attributedefinitions && i.attributedefinitions.length > 0)
.filter((i) => i.typeid == 'OrganizationPreferences')
.map((i) => {
return `
/**
* Organization preferences.
*/
const organization = {
${i.groupdefinitions.attributegroup.map(gd => {
return `
${toConstant(gd.groupid)} : {
${ensureArray(gd, 'attribute') && gd.attribute.map(a => attributeConstant(a))}
}`;
})}
}`;
}).join('\n');
customattrsrc += Array.from(typeExtensions).filter(i => i.attributedefinitions && i.attributedefinitions.length > 0)
.filter((i) => i.typeid == 'SitePreferences')
.map((i) => {
return `
/**
* Site preferences.
*/
const site = {
${i.groupdefinitions.attributegroup.map(gd => {
return `
${toConstant(gd.groupid)} : {
${ensureArray(gd, 'attribute') && gd.attribute.map(a => attributeConstant(a))}
}`;
})}
}`;
}).join('\n');
customattrsrc += `
module.exports = {
organization: organization,
site: site,
};
`;
let prettierconfig = {};
if (fs_1.default.existsSync('.prettierrc')) {
try {
prettierconfig = JSON.parse(fs_1.default.readFileSync('.prettierrc', 'utf8'));
}
catch (e) {
console.log(picocolors_1.default.red(`Unable to parse local .prettierrc: ${e}`));
}
}
prettierconfig.parser = "babel";
prettierconfig.proseWrap = 'always';
let out = customattrsrc;
try {
out = prettier_1.default.format(customattrsrc, prettierconfig);
}
catch (e) {
console.error(picocolors_1.default.red(`Prettier format failed, check generated file at ${dest}\n${e}`));
}
fs_1.default.writeFileSync(dest, out);
}
exports.generateConstants = generateConstants;
function toConstant(val) {
return val.replace(/ /g, '_').replace(/[- \( \)]/g, '_');
}
function mapAttribute(at) {
return `/**
* ${at.description || at.displayname || ''}
*/
${at.attributeid.indexOf('-') > -1 ? "'" + at.attributeid + "'" : at.attributeid}: ${remapType(at)};
`;
}
function remapType(at) {
if (at.type === 'string' || at.type === 'text' || at.type === 'password' || at.type === 'email') {
return 'string';
}
if (at.type === 'double' || at.type === 'int') {
return 'number';
}
if (at.type === 'set-of-string') {
return 'string[]';
}
if (at.type === 'set-of-int') {
return 'number[]';
}
if (at.type === 'date' || at.type === 'datetime') {
return 'Date';
}
if (at.type === 'enum-of-int' || at.type === 'enum-of-double') {
return (at.valuedefinitions || [{ value: 0 }]).map(v => v.value).join(' | ');
}
if (at.type === 'enum-of-string') {
return (at.valuedefinitions || [{ value: '' }]).map(v => `'${v.value}'`).join(' | ');
}
if (at.type === 'image') {
return 'dw.content.MediaFile';
}
if (at.type === 'html') {
return 'dw.content.MarkupText';
}
return at.type;
}
async function parseMeta(source) {
var parser = new xml2js_1.default.Parser({
trim: true,
normalizeTags: true,
mergeAttrs: true,
explicitArray: false,
attrNameProcessors: [function (name) { return name.replace(/-/g, ''); }],
tagNameProcessors: [function (name) { return name.replace(/-/g, ''); }]
});
let exts = await parser.parseStringPromise(fs_1.default.readFileSync(source, 'utf-8'));
if (exts.metadata && exts.metadata.typeextension) {
ensureArray(exts.metadata, 'typeextension');
exts = exts.metadata.typeextension.map((i) => cleanupEntry(i)).filter((i) => i.attributedefinitions);
}
cleanI18n(exts);
// fs.writeFileSync(path.join(process.cwd(), `${path.basename(source)}.json`), JSON.stringify(exts, null, 2));
return exts;
}
function ensureArray(object, field) {
if (object && object[field] && !object[field].length) {
object[field] = [object[field]];
}
return true;
}
function cleanupEntry(i) {
let res = i;
// normalize
if (res.customattributedefinitions) {
res.attributedefinitions = res.customattributedefinitions;
delete res.customattributedefinitions;
}
delete res.systemattributedefinitions;
// cleanup single attributes without array
if (res.attributedefinitions && res.attributedefinitions.attributedefinition && res.attributedefinitions.attributedefinition.attributeid) {
res.attributedefinitions.attributedefinition = [res.attributedefinitions.attributedefinition];
}
if (res.attributedefinitions && res.attributedefinitions.attributedefinition) {
res.attributedefinitions = res.attributedefinitions.attributedefinition;
res.attributedefinitions.forEach((ad) => {
if (ad.valuedefinitions) {
ad.valuedefinitions = ad.valuedefinitions.valuedefinition;
ensureArray(ad, 'valuedefinitions');
}
});
if (res.attributedefinitions.valuedefinitions) {
}
}
return res;
}
function cleanI18n(obj) {
Object
.entries(obj)
.forEach(entry => {
let [k, v] = entry;
if (v !== null && typeof v === 'object' && !v.escape) {
if (v._ && v['xml:lang'] && Object.keys(v).length === 2) {
obj[k] = v._;
// log(`-> replaced ${obj[k]}`);
}
cleanI18n(v);
}
});
}