diff --git a/lib/generator.js b/lib/generator.js index 51c6747..87ad6e6 100644 --- a/lib/generator.js +++ b/lib/generator.js @@ -46,7 +46,7 @@ class Visitor { this.modelPackage = 'models'; this.exceptionPath = path.join(this.outputDir, this.config.package, 'exceptions'); this.exceptionPackage = 'exceptions'; - this.config.clientPath = path.join(this.outputDir, this.config.package, `${_snakeCase(this.config.clientName)}.py`); + this.config.clientPath = path.join(this.outputDir, this.config.package, `${_snakeCase(this.config.clientName, this.config.keywords)}.py`); this.classNamespace = new Map(); // 新增:用于存储已使用的类型 this.isAsyncFunction = false; // 新增:用于标记是否为异步函数 @@ -376,7 +376,7 @@ setup( types.forEach((type) => { let comments = DSL.comment.getFrontComments(this.comments, type.tokenRange[0]); this.visitComments(comments, level + 2); - this.emit(`${_snakeCase(_vid(type.vid))}: `, level + 2); + this.emit(`${_snakeCase(_vid(type.vid), this.config.keywords)}: `, level + 2); this.visitType(type.value); this.emit(' = None\n'); }); @@ -558,7 +558,7 @@ setup( types.forEach((item) => { let comments = DSL.comment.getFrontComments(this.comments, item.tokenRange[0]); this.visitComments(comments, level + 2); - this.emit(`${_snakeCase(_vid(item.vid))}: `, level + 2); + this.emit(`${_snakeCase(_vid(item.vid), this.config.keywords)}: `, level + 2); this.visitType(item.value); this.emit(' = None\n', level); }); @@ -569,7 +569,7 @@ setup( for (var i = 0; i < ast.params.params.length; i++) { const node = ast.params.params[i]; assert.equal(node.type, 'param'); - const name = _avoidKeywords(_snakeCase(_name(node.paramName))); + const name = _avoidKeywords(_snakeCase(_name(node.paramName), this.config.keywords)); this.emit(`${name}: `, level + 4); this.visitType(node.paramType, level); this.emit(','); @@ -607,17 +607,17 @@ setup( if (!moduleDir && innerPath) { let pyPath = innerPath.replace(/(\.tea)$|(\.spec)$|(\.dara)$/gi, '') + '.py'; if (pyPath.startsWith('./') || pyPath.startsWith('../')) { - pyPath = pyPath.split('/').map(dir => _snakeCase(dir)).join(path.sep); + pyPath = pyPath.split('/').map(dir => _snakeCase(dir, this.config.keywords)).join(path.sep); pyPath = path.join(path.dirname(filepath), `${pyPath}`); } else if (pyPath.startsWith('/')) { - pyPath = pyPath.split('/').map(dir => _snakeCase(dir)).join(path.sep); + pyPath = pyPath.split('/').map(dir => _snakeCase(dir, this.config.keywords)).join(path.sep); pyPath = `${pyPath}`; } const classNamespace = this.getClassNamespace(pyPath); const className = this.getInnerClient(aliasId, pyPath); const aliasName = this.getAliasName(className, aliasId); - const filename = _snakeCase(path.basename(pyPath, '.py')); + const filename = _snakeCase(path.basename(pyPath, '.py'), this.config.keywords); this.packageInfo[aliasId] = { aliasName: aliasName || className, clientName: className, @@ -646,7 +646,7 @@ setup( throw new Error(`The '${aliasId}' has no Python supported.`); } let className = _camelCase(pyPkg.clientName || 'client'); - let filename = _snakeCase(className); + let filename = _snakeCase(className, this.config.keywords); let classNamespace = pyPkg.package; let models = 'models'; let exceptions = 'exceptions'; @@ -657,7 +657,7 @@ setup( exceptions = filename + '_exceptions'; const arr = pyPath.split(path.sep).slice(1, -1); arr.map(key => { - classNamespace += '.' + _snakeCase(key); + classNamespace += '.' + _snakeCase(key, this.config.keywords); }); const exportClientName = pyPkg.exports && pyPkg.exports[inner]; className = _camelCase(exportClientName || 'Client'); @@ -756,7 +756,7 @@ setup( for (var i = 0; i < ast.params.length; i++) { const node = ast.params[i]; assert.equal(node.type, 'param'); - const name = _avoidKeywords(_snakeCase(_name(node.paramName))); + const name = _avoidKeywords(_snakeCase(_name(node.paramName), this.config.keywords)); this.emit(`${name}: `, level); this.visitType(node.paramType, level); this.emit(','); @@ -1024,7 +1024,7 @@ setup( node = ast.nodes[i]; let comments = DSL.comment.getFrontComments(this.comments, node.tokenRange[0]); this.visitComments(comments, level); - let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)))); + let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)), this.config.keywords)); const description = this.getAttributes(node, 'description'); if (description) { const descriptions = description.trimEnd().split('\n'); @@ -1101,7 +1101,7 @@ setup( const minimum = this.getAttributes(node, 'minimum') || 0; let comments = DSL.comment.getFrontComments(this.comments, node.tokenRange[0]); this.visitComments(comments, level); - let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)))); + let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)), this.config.keywords)); // 这里判断类中属性是否是必填 if (node.required) { notPass = true; @@ -1200,7 +1200,7 @@ setup( let realName = this.getRealName(node); let comments = DSL.comment.getFrontComments(this.comments, node.tokenRange[0]); this.visitComments(comments, level); - let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)))); + let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)), this.config.keywords)); const hasModel = this.checkFieldHasModel(node.fieldValue); let arr = false; if (hasModel && !this.config.noneEmpty) { @@ -1310,7 +1310,7 @@ setup( let realName = this.getRealName(node); let comments = DSL.comment.getFrontComments(this.comments, node.tokenRange[0]); this.visitComments(comments, level); - let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)))); + let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)), this.config.keywords)); const hasModel = this.checkFieldHasModel(node.fieldValue); let arr = false; if (hasModel && !this.config.noneEmpty) { @@ -1443,7 +1443,7 @@ setup( this.visitExtendOn(extendOn); this.emit(':\n'); this.visitModelBody(modelBody, level + 2, modelName); - this.saveBuffer(path.join(this.modelPath, filename || `_${_snakeCase(modelName)}.py`)); + this.saveBuffer(path.join(this.modelPath, filename || `_${_snakeCase(modelName, this.config.keywords)}.py`)); this.usedTypes = []; this.imports = []; this.output = ''; @@ -1492,7 +1492,7 @@ setup( const ast = models[i]; const modelName = _subModelName(_name(ast.modelName)); modelNames.push(modelName); - this.emit(`from ._${_snakeCase(modelName)} import ${modelName}\n`); + this.emit(`from ._${_snakeCase(modelName, this.config.keywords)} import ${modelName}\n`); } for (let i = 0; i < subModels.length; i++) { @@ -1500,7 +1500,7 @@ setup( const modelName = _subModelName(_name(ast.modelName)); const mainModelName = _name(ast.modelName).split('.')[0]; modelNames.push(modelName); - this.emit(`from ._${_snakeCase(mainModelName)} import ${modelName}\n`); + this.emit(`from ._${_snakeCase(mainModelName, this.config.keywords)} import ${modelName}\n`); } this.emit('\n__all__ = [\n'); @@ -1533,7 +1533,7 @@ setup( let comments = DSL.comment.getFrontComments(this.comments, node.tokenRange[0]); this.visitComments(comments, level); } - let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)))); + let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)), this.config.keywords)); if (param === 'name' && type === 'exception') { continue; } @@ -1549,7 +1549,7 @@ setup( this.emit('{\n'); for (let i = 0; i < ast.extendFileds.length; i++) { node = ast.extendFileds[i]; - let value = _snakeCase(_escape(_name(node.fieldName))); + let value = _snakeCase(_escape(_name(node.fieldName)), this.config.keywords); let key = _avoidKeywords(_escape(_name(node.fieldName))); if (key === 'name' && type === 'exception') { continue; @@ -1561,7 +1561,7 @@ setup( this.emit('\n'); for (let i = 0; i < ast.extendFileds.length; i++) { node = ast.extendFileds[i]; - let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)))); + let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)), this.config.keywords)); if (param === 'name' && type === 'exception') { continue; } @@ -1582,7 +1582,7 @@ setup( node = ast.nodes[i]; let comments = DSL.comment.getFrontComments(this.comments, node.tokenRange[0]); this.visitComments(comments, level); - let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)))); + let param = _avoidKeywords(_snakeCase(_escape(_name(node.fieldName)), this.config.keywords)); if (param === 'name') { continue; } @@ -1607,7 +1607,7 @@ setup( this.visitExtendOn(extendOn, 'exception'); this.emit(':\n'); this.visitEcxceptionBody(exceptionBody, extendOn, exceptionName, level + 2); - this.saveBuffer(path.join(this.exceptionPath, `_${_snakeCase(exceptionName)}.py`)); + this.saveBuffer(path.join(this.exceptionPath, `_${_snakeCase(exceptionName, this.config.keywords)}.py`)); this.usedTypes = []; this.imports = []; this.output = ''; @@ -1628,7 +1628,7 @@ setup( const ast = excpetions[i]; const exceptionName = _subModelName(_name(ast.exceptionName)); exceptionNames.push(exceptionName); - this.emit(`from ._${_snakeCase(exceptionName)} import ${exceptionName}Exception\n`); + this.emit(`from ._${_snakeCase(exceptionName, this.config.keywords)} import ${exceptionName}Exception\n`); } this.emit('\n__all__ = [\n'); @@ -1642,7 +1642,7 @@ setup( assert.equal(ast.type, 'model'); const modelName = _subModelName(_name(ast.modelName)); const mainModelName = _name(ast.modelName).split('.')[0]; - this.visitModel(ast.modelBody, modelName, ast.extendOn, level, `_${_snakeCase(mainModelName)}.py`); + this.visitModel(ast.modelBody, modelName, ast.extendOn, level, `_${_snakeCase(mainModelName, this.config.keywords)}.py`); } visitObjectFieldValue(ast, level) { @@ -1673,7 +1673,7 @@ setup( if (ast.type === 'objectField') { // TODO 这里粗暴处理的双引号,可以考虑优化 var key = _escape(_name(ast.fieldName) || _string(ast.fieldName)).replace(/['"]/g, ''); - this.emit(`${_avoidKeywords(_snakeCase(key))} = `, level + 2); + this.emit(`${_avoidKeywords(_snakeCase(key, this.config.keywords))} = `, level + 2); this.visitObjectFieldValue(ast.expr, level + 2); if (!end) { this.emit(',\n'); @@ -1740,7 +1740,7 @@ setup( visitMethodCall(ast, level) { assert.equal(ast.left.type, 'method_call'); const name = _name(ast.left.id); - const functionName = _avoidKeywords(_snakeCase(name)); + const functionName = _avoidKeywords(_snakeCase(name, this.config.keywords)); const sse = ast.notes && ast.notes.find(note => note.note.lexeme === '@sse'); const isSSE = sse && sse.arg.value; if (name.startsWith('$') && this.builtin[name]) { @@ -1754,7 +1754,7 @@ setup( } else if (ast.isAsync && this.isAsyncFunction) { this.emit(`${isSSE ? '' : 'await '}${this.className}.${functionName}_async`); } else { - const functionName = _snakeCase(name); + const functionName = _snakeCase(name, this.config.keywords); this.emit(`${this.className}.${functionName}`); } this.visitArgs(ast.args, level); @@ -1774,12 +1774,12 @@ setup( this.builtin[ast.builtinModule][method](ast, level, async); } else { if (ast.left.id.tag === DSL.Tag.Tag.VID) { - this.emit(`self.${_snakeCase(_vid(ast.left.id))}`); + this.emit(`self.${_snakeCase(_vid(ast.left.id), this.config.keywords)}`); } else { - const aliasId = _snakeCase(_name(ast.left.id)); + const aliasId = _snakeCase(_name(ast.left.id), this.config.keywords); this.emit(aliasId); } - this.emit(`.${(_avoidKeywords(_snakeCase(method)))}`); + this.emit(`.${(_avoidKeywords(_snakeCase(method, this.config.keywords)))}`); if (async) { this.emit('_async'); } @@ -1798,7 +1798,7 @@ setup( const aliasId = _name(ast.left.id); let clientName = this.getModelName('', aliasId, 'module'); - const functionName = _avoidKeywords(_snakeCase(_name(ast.left.propertyPath[0]))); + const functionName = _avoidKeywords(_snakeCase(_name(ast.left.propertyPath[0]), this.config.keywords)); const sse = ast.notes && ast.notes.find(note => note.note.lexeme === '@sse'); const isSSE = sse && sse.arg.value; @@ -1877,9 +1877,9 @@ setup( visitPropertyAccess(ast, env = {}) { assert.ok(ast.type === 'property_access' || ast.type === 'property'); - var id = _snakeCase(_name(ast.id)); + var id = _snakeCase(_name(ast.id), this.config.keywords); if (ast.id.tag === Tag.VID) { - id = `self.${_snakeCase(_vid(ast.id))}`; + id = `self.${_snakeCase(_vid(ast.id), this.config.keywords)}`; } var expr = _avoidKeywords(id); const prefix = env.left ? '[' : '.get('; @@ -1889,7 +1889,7 @@ setup( for (var i = 0; i < ast.propertyPath.length; i++) { var name = _name(ast.propertyPath[i]); if (current.type === 'model') { - expr += `.${_avoidKeywords(_snakeCase(name))}`; + expr += `.${_avoidKeywords(_snakeCase(name, this.config.keywords))}`; } else { expr += `${prefix}"${name}"${suffix}`; } @@ -1915,10 +1915,10 @@ setup( if (ast.inferred && ast.inferred.type === 'basic' && ast.inferred.name === 'class') { this.emit(this.getModelName('', _name(ast.id), 'module')); } else { - this.emit(_avoidKeywords(_snakeCase(_name(ast.id)))); + this.emit(_avoidKeywords(_snakeCase(_name(ast.id), this.config.keywords))); } } else if (ast.type === 'virtualVariable') { - this.emit(`self.${_snakeCase(_vid(ast.vid))}`); + this.emit(`self.${_snakeCase(_vid(ast.vid), this.config.keywords)}`); } else if (ast.type === 'decrement') { this.visitExpr(ast.expr, level, { left: true }); this.emit('-= 1'); @@ -2055,9 +2055,9 @@ setup( assert.equal(ast.type, 'map_access'); let expr; if (ast.id.tag === DSL.Tag.Tag.VID) { - expr = `self.${_snakeCase(_vid(ast.id))}`; + expr = `self.${_snakeCase(_vid(ast.id), this.config.keywords)}`; } else { - expr = `${_avoidKeywords(_snakeCase(_name(ast.id)))}`; + expr = `${_avoidKeywords(_snakeCase(_name(ast.id), this.config.keywords))}`; } const prefix = env.left ? '[' : '.get('; const suffix = env.left ? ']' : ')'; @@ -2066,7 +2066,7 @@ setup( for (var i = 0; i < ast.propertyPath.length; i++) { var name = _name(ast.propertyPath[i]); if (current.type === 'model') { - expr += `.${_avoidKeywords(_snakeCase(name))}`; + expr += `.${_avoidKeywords(_snakeCase(name, this.config.keywords))}`; } else { expr += `${prefix}"${name}"${suffix}`; } @@ -2083,16 +2083,16 @@ setup( let expr; if (ast.id.tag === DSL.Tag.Tag.VID) { // 这个判断很奇怪诶 - expr = `self.${_snakeCase(_vid(ast.id))}`; + expr = `self.${_snakeCase(_vid(ast.id, this.config.keywords))}`; } else { - expr = `${_avoidKeywords(_snakeCase(_name(ast.id)))}`; + expr = `${_avoidKeywords(_snakeCase(_name(ast.id), this.config.keywords))}`; } if (ast.propertyPath && ast.propertyPath.length) { var current = ast.id.inferred; for (var i = 0; i < ast.propertyPath.length; i++) { var name = _name(ast.propertyPath[i]); if (current.type === 'model') { - expr += `.${_avoidKeywords(_snakeCase(name))}`; + expr += `.${_avoidKeywords(_snakeCase(name, this.config.keywords))}`; } else { expr += `["${name}"]`; } @@ -2250,7 +2250,7 @@ setup( this.emit('k, v in '); this.visitExpr(ast.list, level); } else { - this.emit(`${_avoidKeywords(_snakeCase(_name(ast.id)))} in `); + this.emit(`${_avoidKeywords(_snakeCase(_name(ast.id), this.config.keywords))} in `); this.visitExpr(ast.list, level); } this.emit(':\n'); @@ -2306,9 +2306,9 @@ setup( this.emit('', level); this.visitPropertyAccess(ast.left, { left: true }); } else if (ast.left.type === 'virtualVariable') { // vid - this.emit(`self.${_snakeCase(_vid((ast.left.vid)))}`, level); + this.emit(`self.${_snakeCase(_vid((ast.left.vid)), this.config.keywords)}`, level); } else if (ast.left.type === 'variable') { - this.emit(`${_avoidKeywords(_snakeCase(_name(ast.left.id)))}`, level); + this.emit(`${_avoidKeywords(_snakeCase(_name(ast.left.id), this.config.keywords))}`, level); } else if (ast.left.type === 'map_access') { // 声明时不能用get去赋值 this.emit('', level); @@ -2333,7 +2333,7 @@ setup( // 实例初始化 new的地方 visitDeclare(ast, level) { - var id = _avoidKeywords(_snakeCase(_name(ast.id))); + var id = _avoidKeywords(_snakeCase(_name(ast.id), this.config.keywords)); this.emit(`${id}`, level); if (id === 'new_full_str') { this.emit(''); @@ -2399,7 +2399,7 @@ setup( // this.visitAnnotation(ast.annotation, level); // let comments = DSL.comment.getFrontComments(this.comments, ast.tokenRange[0]); // this.visitComments(comments, level); - const functionName = _avoidKeywords(_snakeCase(_name(ast.functionName))); + const functionName = _avoidKeywords(_snakeCase(_name(ast.functionName), this.config.keywords)); if (ast.isStatic) { this.emit('@staticmethod\n', level); @@ -2477,7 +2477,7 @@ setup( let comments = DSL.comment.getFrontComments(this.comments, ast.tokenRange[0]); this.visitComments(comments, level); // set api name to _snakeCase - const apiName = _avoidKeywords(_snakeCase(_name(ast.apiName))); + const apiName = _avoidKeywords(_snakeCase(_name(ast.apiName), this.config.keywords)); this.isStaticFunction = false; this.emit(`def ${apiName}`, level); this.visitParams(ast.params, level, true); @@ -2755,7 +2755,7 @@ setup( if (type === 'model' && moduleName) { const { namemespace, models } = this.packageInfo[moduleName]; - const aliasName = `${_snakeCase(moduleName.replace(/-/g, ''))}_models`; + const aliasName = `${_snakeCase(moduleName.replace(/-/g, ''), this.config.keywords)}_models`; this.imports.push({ aliasName, packageName: namemespace, @@ -2776,7 +2776,7 @@ setup( if (type === 'exception' && moduleName) { const { namemespace, exceptions } = this.packageInfo[moduleName]; - const aliasName = `${_snakeCase(moduleName.replace(/-/g, ''))}_exceptions`; + const aliasName = `${_snakeCase(moduleName.replace(/-/g, ''), this.config.keywords)}_exceptions`; this.imports.push({ aliasName, packageName: namemespace, diff --git a/lib/helper.js b/lib/helper.js index c09f9e4..62a8c93 100644 --- a/lib/helper.js +++ b/lib/helper.js @@ -213,13 +213,34 @@ function _camelCase(str, split = '_') { return str; } -function _snakeCase(str) { +function _snakeCase(str, keys = []) { if (!str) { return ''; } + + // Convert keys to array if it's a single string + if (typeof keys === 'string') { + keys = [keys]; + } + + let result = str; + + // First, handle the keywords by replacing them with placeholders + const placeholders = {}; + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (key && result.includes(key)) { + const placeholder = `@@_${i}@@`; + placeholders[placeholder] = `_${key.toLowerCase()}_`; + result = result.split(key).join(placeholder); + } + } + + // Process the string normally let res = ''; let tmp = ''; - for (const c of str) { + + for (const c of result) { if (/[A-Z|0-9]/.test(c)) { tmp += c; } else { @@ -230,13 +251,34 @@ function _snakeCase(str) { res += c; } } + if (tmp.length > 0) { - res += '_' + tmp.toLowerCase(); + res += (res === '' ? '' : '_') + tmp.toLowerCase(); } + res = res.replace(/-/g, '_'); + + // Clean up any double underscores + res = res.replace(/_+/g, '_'); + + // Restore the special keywords from placeholders + for (const [placeholder, value] of Object.entries(placeholders)) { + const regex = new RegExp(placeholder, 'g'); + res = res.replace(regex, value); + } + + res = res.replace(/_+/g, '_'); + + // Remove leading underscore if original string didn't start with one if (res[0] === '_' && str[0] !== '_') { res = res.substring(1); } + + // Remove trailing underscore if original string didn't end with one + if (res[res.length - 1] === '_' && str[str.length - 1] !== '_') { + res = res.substring(0, res.length - 1); + } + return res; } diff --git a/tests/expected/complex/tea_python_tests/client.py b/tests/expected/complex/tea_python_tests/client.py index ee53c00..0a87db5 100644 --- a/tests/expected/complex/tea_python_tests/client.py +++ b/tests/expected/complex/tea_python_tests/client.py @@ -20,7 +20,7 @@ class Client(SourceClient): _protocol: str = None _pathname: str = None - __strs: List[str] = None + _strs: List[str] = None _comple_list: List[List[str]] = None _endpoint_map: Dict[str, str] = None _configs: List[source_models.Config] = None @@ -206,11 +206,11 @@ def complex_1( any_map = {} any_map[item] = 'test' break - self.__strs = request.strs + self._strs = request.strs self._protocol = 'test' self._endpoint_map.get(self._protocol) self._endpoint_map['test'] = 'ok' - request.strs = self.__strs + request.strs = self._strs _request.protocol = self._protocol _request.port = request.num _request.method = 'GET' @@ -421,11 +421,11 @@ async def complex_1_async( any_map = {} any_map[item] = 'test' break - self.__strs = request.strs + self._strs = request.strs self._protocol = 'test' self._endpoint_map.get(self._protocol) self._endpoint_map['test'] = 'ok' - request.strs = self.__strs + request.strs = self._strs _request.protocol = self._protocol _request.port = request.num _request.method = 'GET' @@ -611,6 +611,7 @@ def complex_3( x = y resp = _response req = source_models.Request( + cors_rules = 'test', accesskey = request.access_key, region = resp.status_message ) @@ -653,6 +654,7 @@ async def complex_3_async( x = y resp = _response req = source_models.Request( + cors_rules = 'test', accesskey = request.access_key, region = resp.status_message ) diff --git a/tests/expected/function/tea_python_tests/client.py b/tests/expected/function/tea_python_tests/client.py index ed627ab..d0de57c 100644 --- a/tests/expected/function/tea_python_tests/client.py +++ b/tests/expected/function/tea_python_tests/client.py @@ -63,3 +63,15 @@ def a_params(self) -> None: async def a_params_async(self) -> None: await self.hello_params_async('a', 'b') + + def test_jwt_with_option(self) -> None: + self.hello_params('a', 'b') + + async def test_jwt_with_option_async(self) -> None: + await self.hello_params_async('a', 'b') + + def test_oauth2_for_option(self) -> None: + self.hello_params('a', 'b') + + async def test_oauth2_for_option_async(self) -> None: + await self.hello_params_async('a', 'b') diff --git a/tests/expected/model/tea_python_tests/models/_my_model.py b/tests/expected/model/tea_python_tests/models/_my_model.py index 67672ec..f7930b8 100644 --- a/tests/expected/model/tea_python_tests/models/_my_model.py +++ b/tests/expected/model/tea_python_tests/models/_my_model.py @@ -14,6 +14,10 @@ class MyModel(DaraModel): def __init__( self, model: main_models.MyModelModel = None, + cors_rules: str = None, + cors_rules_cors_r: str = None, + xml_parser_http_message: str = None, + test_oauth2_name: str = None, stringfield: str = None, bytesfield: bytes = None, stringarrayfield: List[str] = None, @@ -60,6 +64,10 @@ def __init__( link: str = None, ): self.model = model + self.cors_rules = cors_rules + self.cors_rules_cors_r = cors_rules_cors_r + self.xml_parser_http_message = xml_parser_http_message + self.test_oauth2_name = test_oauth2_name self.stringfield = stringfield self.bytesfield = bytesfield self.stringarrayfield = stringarrayfield @@ -109,6 +117,10 @@ def validate(self): self.validate_required(self.model, 'model') if self.model: self.model.validate() + self.validate_required(self.cors_rules, 'cors_rules') + self.validate_required(self.cors_rules_cors_r, 'cors_rules_cors_r') + self.validate_required(self.xml_parser_http_message, 'xml_parser_http_message') + self.validate_required(self.test_oauth2_name, 'test_oauth2_name') self.validate_required(self.stringfield, 'stringfield') self.validate_required(self.bytesfield, 'bytesfield') self.validate_required(self.stringarrayfield, 'stringarrayfield') @@ -220,6 +232,18 @@ def to_map(self): if self.model is not None: result['model'] = self.model.to_map() + if self.cors_rules is not None: + result['CORSRules'] = self.cors_rules + + if self.cors_rules_cors_r is not None: + result['CORSRulesCORSR'] = self.cors_rules_cors_r + + if self.xml_parser_http_message is not None: + result['XMLParserHTTPMessage'] = self.xml_parser_http_message + + if self.test_oauth2_name is not None: + result['TestOAuth2Name'] = self.test_oauth2_name + if self.stringfield is not None: result['stringfield'] = self.stringfield @@ -405,6 +429,18 @@ def from_map(self, m: dict = None): temp_model = main_models.MyModelModel() self.model = temp_model.from_map(m.get('model')) + if m.get('CORSRules') is not None: + self.cors_rules = m.get('CORSRules') + + if m.get('CORSRulesCORSR') is not None: + self.cors_rules_cors_r = m.get('CORSRulesCORSR') + + if m.get('XMLParserHTTPMessage') is not None: + self.xml_parser_http_message = m.get('XMLParserHTTPMessage') + + if m.get('TestOAuth2Name') is not None: + self.test_oauth2_name = m.get('TestOAuth2Name') + if m.get('stringfield') is not None: self.stringfield = m.get('stringfield') diff --git a/tests/fixtures/complex/Darafile b/tests/fixtures/complex/Darafile index 29fd45b..a59506e 100644 --- a/tests/fixtures/complex/Darafile +++ b/tests/fixtures/complex/Darafile @@ -5,5 +5,10 @@ "main": "./main.dara", "libraries": { "Source": "alibabacloud:Import:*" + }, + "python": { + "keywords": [ + "CORS" + ] } } \ No newline at end of file diff --git a/tests/fixtures/complex/libraries/Darafile b/tests/fixtures/complex/libraries/Darafile index 510790a..bc92b7a 100644 --- a/tests/fixtures/complex/libraries/Darafile +++ b/tests/fixtures/complex/libraries/Darafile @@ -23,7 +23,10 @@ }, "python": { "package": "Source", - "clientName": "source_client" + "clientName": "source_client", + "keywords": [ + "CORS" + ] }, "python2": { "package": "Source", diff --git a/tests/fixtures/complex/libraries/import.dara b/tests/fixtures/complex/libraries/import.dara index 14edb83..ec33880 100644 --- a/tests/fixtures/complex/libraries/import.dara +++ b/tests/fixtures/complex/libraries/import.dara @@ -30,6 +30,7 @@ static function parse(c: class): void; static async function asyncFunc(): void; model Request = { + CORSRules: string, accesskey?: string(name='accesskey', description='accesskey'), region?: string(name='region', description='region'), instance: { diff --git a/tests/fixtures/complex/main.dara b/tests/fixtures/complex/main.dara index fb650d7..9566cba 100644 --- a/tests/fixtures/complex/main.dara +++ b/tests/fixtures/complex/main.dara @@ -300,6 +300,7 @@ api Complex3(request: ComplexRequest, name: string): ComplexRequest { } var resp = __response; var req = new Source.Request{ + CORSRules = "test", accesskey = request.accessKey, region = resp.statusMessage }; diff --git a/tests/fixtures/function/Darafile b/tests/fixtures/function/Darafile index 67264f0..ee6a71f 100644 --- a/tests/fixtures/function/Darafile +++ b/tests/fixtures/function/Darafile @@ -2,5 +2,11 @@ "scope": "alibabacloud", "name": "main", "version": "0.0.1", - "main": "./main.dara" + "main": "./main.dara", + "python": { + "keywords": [ + "JWT", + "OAuth2" + ] + } } \ No newline at end of file diff --git a/tests/fixtures/function/main.dara b/tests/fixtures/function/main.dara index 4ab0618..d4c8203 100644 --- a/tests/fixtures/function/main.dara +++ b/tests/fixtures/function/main.dara @@ -34,4 +34,12 @@ static async function helloInterface(): void; async function aParams(): void { helloParams("a", "b"); +} + +async function testJWTWithOption(): void { + helloParams("a", "b"); +} + +async function testOAuth2forOption(): void { + helloParams("a", "b"); } \ No newline at end of file diff --git a/tests/fixtures/model/Darafile b/tests/fixtures/model/Darafile index ea78870..0c0f785 100644 --- a/tests/fixtures/model/Darafile +++ b/tests/fixtures/model/Darafile @@ -5,5 +5,13 @@ "main": "./main.dara", "libraries": { "Source": "darabonba:Import:*" + }, + "python": { + "keywords": [ + "CORS", + "XML", + "HTTP", + "OAuth2" + ] } } \ No newline at end of file diff --git a/tests/fixtures/model/main.dara b/tests/fixtures/model/main.dara index ffc7b37..e1e9e72 100644 --- a/tests/fixtures/model/main.dara +++ b/tests/fixtures/model/main.dara @@ -28,6 +28,10 @@ model MyModel = { str: string }, }, + CORSRules: string, + CORSRulesCORSR: string, + XMLParserHTTPMessage: string, + TestOAuth2Name: string, stringfield: string, bytesfield: bytes, stringarrayfield: [ string ],