UNPKG

sfcc-dts

Version:

> High quality Salesforce Commerce Cloud type definitions. A dw-api-types "done right"

252 lines (247 loc) 9.13 kB
#!/usr/bin/env node "use strict"; 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); } }); }