lib/helper.js (166 lines of code) (raw):

'use strict'; const fs = require('fs'); const path = require('path'); const xml2js = require('xml2js'); const marked = require('marked'); marked.use({ mangle: false, headerIds: false }); const builtinModels = [ '$Request', '$Response', '$Error', '$SSEEvent', '$Model', '$RuntimeOptions', '$ExtendsParameters', '$RetryOptions', '$ResponseError', '$FileField' ]; const exceptionFields = ['message', 'code', 'data', 'statusCode', 'description', 'accessDeniedDetail']; // const typeMap = { // any: 'object', // number: 'int?', // boolean: 'bool?', // object: 'Dictionary<string, object>', // integer: 'int?', // map: 'Dictionary<string, string>', // uint16: 'ushort?', // int16: 'short?', // uint8: 'byte', // int8: 'sbyte', // uint32: 'uint?', // int32: 'int?', // uint64: 'ulong?', // int64: 'long?', // readable: 'Stream', // writable: 'Stream', // $Request: 'Request', // $Response: 'Response', // $Model: 'Model', // $URL: 'URL', // $Date: 'Date', // $File: 'File', // $Form: 'FormUtils', // $Number: 'MathUtils', // $XML: 'XmlUtils', // $String: 'StringUtils', // $ResponseError: 'DaraResponseException', // $Error: 'DaraException', // $RetryOptions: 'RetryOptions', // $RuntimeOptions: 'RuntimeOptions', // $SSEEvent: 'SSEEvent', // $ExtendsParameters: 'ExtendsParameters', // void: 'void', // bytes: 'byte[]', // float: 'float?', // double: 'double?', // class: 'Type', // long: 'long?', // ulong: 'ulong?', // }; const builtinMap = { $URL: 'URL', $Stream: 'StreamUtils', $Date: 'Date', $File: 'File', $Form: 'FormUtils', $JSON: 'JSONUtils', $Number: 'MathUtils', $XML: 'XmlUtils', $String: 'StringUtils', }; const REQUEST = 'request_'; const RESPONSE = 'response_'; function _escape(str) { return str.includes('-') ? `'${str}'` : str; } function _name(str) { if (str.lexeme === '__request') { return REQUEST; } if (str.lexeme === '__response') { return RESPONSE; } return str.lexeme || str.name; } function _upperFirst(str) { return str[0].toUpperCase() + str.substring(1); } // 将目录的每一级的首字母大写 function _upperPath(filePath) { if (filePath) { const parts = filePath.split(path.sep).map(part => _upperFirst(part)); return parts.join(path.sep); } return ''; } // 通过filepath获取namespace的剩余部分,例如Lib/Util.cs -> Lib -> ${this.namespace}.Lib function _nameSpace(filePath) { return path.dirname(_upperPath(filePath)) !== '.' ? path.dirname(_upperPath(filePath)).replace(new RegExp(`\\${path.sep}`, 'g'), '.') : ''; } function _subModelName(name) { return name.split('.').map((name) => _upperFirst(name)).join(''); } function _lowerFirst(str) { return str[0].toLowerCase() + str.substring(1); } function _string(str) { if (str.string === '""') { return '\\"\\"'; } str.string = str.string.replace(/\\/g, '\\\\').replace(/\n/g, '\\n'); return str.string.replace(/([^\\])"+|^"/g, function (str) { return str.replace(/"/g, '\\"'); }); } // function _type(name) { // if (typeMap[name]) { // name = typeMap[name]; // } // return name; // } function _avoidReserveName(name) { const reserves = [ 'abstract', 'as', 'base', 'bool', 'break', 'byte', 'case', 'catch', 'char', 'checked', 'class', 'const', 'continue', 'decimal', 'default', 'delegate', 'do', 'double', 'else', 'enum', 'event', 'explicit', 'extern', 'false', 'finally', 'fixed', 'float', 'for', 'foreach', 'goto', 'if', 'implicit', 'in', 'int', 'interface', 'internal', 'is', 'lock', 'long', 'namespace', 'new', 'null', 'object', 'operator', 'out', 'override', 'params', 'private', 'protected', 'public', 'readonly', 'ref', 'return', 'sbyte', 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'uint', 'ulong', 'unchecked', 'unsafe', 'ushort', 'using', 'virtual', 'void', 'volatile', 'while', 'Equals', 'model' ]; if (reserves.indexOf(name) !== -1) { return `${name}_`; } return name; } function remove(...filesPath) { filesPath.forEach(filePath => { if (fs.existsSync(filePath)) { if (fs.statSync(filePath).isDirectory()) { const files = fs.readdirSync(filePath); files.forEach((file, index) => { let curPath = path.join(filePath, file); if (fs.statSync(curPath).isDirectory()) { remove(curPath); } else { fs.unlinkSync(curPath); } }); fs.rmdirSync(filePath); } else { fs.unlinkSync(filePath); } } }); } function _vid(vid) { return `_${_name(vid).substr(1)}`; } function parse(xml) { let _err, _result; xml2js.parseString(xml, function (err, result) { if (err) { _err = err; return; } _result = result; }); if (_err) { throw _err; } return _result; } function render(template, params = {}) { Object.keys(params).forEach((key) => { template = template.split('${' + key + '}').join(params[key]); }); return template; } function _format(str) { return str.replace(/<p>/g, '<para>') .replace(/<\/p>/g, '</para>') .replace(/<ul>/g, '<list type="bullet">') .replace(/<\/ul>/g, '</list>') .replace(/<li>/g, '<item><description>') .replace(/<\/li>/g, '</description></item>') .replace(/<strong>/g, '<b>') .replace(/<\/strong>/g, '</b>') .replace(/<code>/g, '<c>') .replace(/<\/code>/g, '</c>') .replace(/<blockquote>/g, '<remarks>') .replace(/<\/blockquote>/g, '</remarks>'); } function md2Html(mdText) { let htmlText = marked.parse(mdText).trimEnd(); return htmlText; } function _isBuiltinModel(name) { return builtinModels.includes(name); } function _isBinaryOp(type) { const op = [ 'or', 'eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'add', 'subtract', 'div', 'multi', 'and' ]; return op.includes(type); } module.exports = { _name, _upperFirst, _string, _lowerFirst, _isBinaryOp, _avoidReserveName, remove, _vid, parse, render, _format, md2Html, _escape, _subModelName, _upperPath, _nameSpace, builtinMap, _isBuiltinModel, exceptionFields };