kb_syntax.py•60.7 kB
"""Magic-API 脚本语法知识库。"""
from __future__ import annotations
import textwrap
from typing import Any, Dict, List
# Magic-Script 语法知识块
SYNTAX_KNOWLEDGE: Dict[str, Dict[str, Any]] = {
"keywords": {
"title": "关键字与保留字",
"summary": "Magic-Script 使用 Java 风格的关键字,注意 `exit` 在 v0.5.0+ 直接终止脚本。",
"sections": [
{
"heading": "流程控制",
"items": [
"`if` / `else`:条件分支,0、空串、空集合视为 false",
"`for ... in`:可遍历 List、Map、range(起,止)" ,
"`while`:与 Java 类似,配合 `break`、`continue`",
],
},
{
"heading": "异常与提前结束",
"items": [
"`try` / `catch` / `finally`:捕获异常,结合 `response.error` 统一输出",
"`exit code, message`:直接结束脚本并返回指定响应 (0.5.0+)",
"`assert`:1.3.4+ 内置断言,失败抛出异常",
],
},
],
"doc": "https://www.ssssssss.org/magic-api/pages/base/script/#%E5%85%B3%E9%94%AE%E5%AD%97",
},
"operators": {
"title": "运算符与短路逻辑",
"summary": "遵循 Java 基本规则,但 0.4.6+ 对非布尔短路与 JS 对齐。",
"sections": [
{
"heading": "算术与赋值",
"code": textwrap.dedent(
'''
var total = 1 + 2 * 3 / 4 % 2;
total += 5; // 复合赋值
'''
).strip(),
"notes": "复合赋值支持 +=/-=/...,但 `range` 循环内不支持。",
},
{
"heading": "逻辑增强",
"code": textwrap.dedent(
'''
var left0 = 0 && 'hello'; // 0 (v0.4.6+)
var right0 = 0 || 'world'; // 'world'
'''
).strip(),
"notes": "空集合、null、0 均视为 false,确保空值校验。",
},
],
"doc": "https://www.ssssssss.org/magic-api/pages/base/script/#%E8%BF%90%E7%AE%97%E7%AC%A6",
},
"types": {
"title": "数据类型与转换",
"summary": "支持 Java 基础数值、集合、Lambda 与 Pattern 类型。",
"sections": [
{
"heading": "字面量",
"items": [
"`123l` Long、`123m` BigDecimal、`/\\d+/g` 正则",
'多行 SQL 使用 `"""` 包裹',
],
},
{
"heading": "类型转换",
"code": textwrap.dedent(
'''
var amount = '123.45'::decimal(0);
var date = '2020-01-01'::date('yyyy-MM-dd');
var fallback = 'abc'::int(111); // 默认值
'''
).strip(),
"notes": "`::type(default)` 支持默认值,减少空指针判断。",
},
],
"doc": "https://www.ssssssss.org/magic-api/pages/base/script/#%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B",
},
"collections": {
"title": "集合操作",
"summary": "内置高阶函数 `map`/`filter`/`each`/`join`,支持解构展开。",
"sections": [
{
"heading": "遍历与过滤",
"code": textwrap.dedent(
'''
var users = db.select("select id,name from user");
return users.filter((u) => u.status == 1)
.map(u => u.name);
'''
).strip(),
},
{
"heading": "展开语法",
"code": "var merged = [1,2,...[3,4]]; // [1,2,3,4]",
"notes": "`{key1:1,...map}` 可合并 Map,注意索引键为字符串。",
},
],
"doc": "https://www.ssssssss.org/magic-api/pages/extension/collection/",
},
"db": {
"title": "数据库与事务",
"summary": "`db` 模块支持 CRUD、事务与缓存。务必使用参数绑定。",
"sections": [
{
"heading": "查询",
"code": textwrap.dedent(
'''
import response;
var rows = db.select("""
select id,name from users
where status = #{status}
""", {status: 1});
return response.json(rows);
'''
).strip(),
"notes": "参数一律使用 `#{}`,避免 `${}` 拼接 SQL。",
},
{
"heading": "事务",
"code": textwrap.dedent(
'''
return db.transaction(() => {
var id = db.insert("insert into t(a) values(#{a})", {a:1});
if(!id){ exit 500,'插入失败'; }
return {success:true, id:id};
});
'''
).strip(),
"notes": "异常抛出自动回滚,可自定义 `exit` 返回业务码。",
},
{
"heading": "链式表操作",
"code": textwrap.dedent(
'''
var result = db.table("magic_api_info")
.columns("api_method", "api_path")
.page();
'''
).strip(),
"notes": "使用 `db.table(...).page()` 继承全局分页配置,可在 `config/spring-boot/#page` 自定义页码参数。",
},
],
"doc": "https://www.ssssssss.org/magic-api/pages/base/db/",
},
"response": {
"title": "响应统一封装",
"summary": "导入 `response` 模块统一输出 JSON/Page/Text。",
"sections": [
{
"heading": "分页响应",
"code": textwrap.dedent(
'''
import response;
return response.page(total, records);
'''
).strip(),
},
{
"heading": "错误输出",
"code": textwrap.dedent(
'''
import response;
if(list.isEmpty()){
return response.error(404, '数据不存在');
}
'''
).strip(),
},
],
"doc": "https://www.ssssssss.org/magic-api/pages/module/response/",
},
"loops": {
"title": "循环语句",
"summary": "支持 for...in 循环遍历集合和指定次数循环。",
"sections": [
{
"heading": "遍历集合",
"code": textwrap.dedent(
'''
import 'java.lang.System' as System;
var list = [1,2,3];
for(index,item in list){ //如果不需要index,也可以写成for(item in list)
System.out.println(index + ":" + item);
}
// 结果:
// 0:1
// 1:2
// 2:3
'''
).strip(),
},
{
"heading": "指定次数循环",
"code": textwrap.dedent(
'''
var sum = 0;
for(value in range(0,100)){ //包括0包括100
sum = sum + value; //不支持+= -= *= /= ++ -- 这种运算
}
return sum; // 结果:5050
'''
).strip(),
},
{
"heading": "遍历Map",
"code": textwrap.dedent(
'''
import 'java.lang.System' as System;
var map = {
key1 : 123,
key2 : 456
};
for(key,value in map){ //如果不需要key,也可以写成for(value in map)
System.out.println(key + ":" + value);
}
// 结果:
// key1:123
// key2:456
'''
).strip(),
},
],
"doc": "https://www.ssssssss.org/magic-api/pages/base/script/#for%E5%BE%AA%E7%8E%AF",
},
"imports": {
"title": "导入语句",
"summary": "支持导入Java类、Spring Bean和自定义模块。",
"sections": [
{
"heading": "导入Java类",
"code": textwrap.dedent(
'''
import 'java.lang.System' as System;//导入静态类并赋值给system作为变量
import 'javax.sql.DataSource' as ds;//从spring中获取DataSource并将值赋值给ds作为变量
import 'org.apache.commons.lang3.StringUtils' as string;//导入静态类并赋值给ds作为变量
import 'java.text.*' //此写法跟Java一致,在1.3.4中新增
System.out.println('调用System打印');//调用静态方法
'''
).strip(),
},
{
"heading": "导入模块",
"code": textwrap.dedent(
'''
import log; //导入log模块,并定义一个与模块名相同的变量名
//import log as logger; //导入log模块,并赋值给变量 logger
log.info('Hello {}','Magic API!')
'''
).strip(),
},
],
"doc": "https://www.ssssssss.org/magic-api/pages/base/script/#Import%E5%AF%BC%E5%85%A5",
},
"async": {
"title": "异步调用",
"summary": "使用 async 关键字实现异步操作,提高并发性能。",
"sections": [
{
"heading": "异步方法调用",
"code": textwrap.dedent(
'''
// 使用async关键字,会启动一个线程去执行,返回Future类型,并不等待结果继续执行后续代码
var user1 = async db.select("select * from sys_user where id = 1");
var user2 = async db.select("select * from sys_user where id = 2");
// 调用get方法表示阻塞等待获取结果
return [user1.get(),user2.get()];
'''
).strip(),
},
{
"heading": "异步Lambda",
"code": textwrap.dedent(
'''
var list = [];
for(index in range(1,10)){
// 当异步中使用外部变量时,为了确保线程安全的变量,可以将其放在形参中
list.add(async (index)=>db.select("select * from sys_user where id = #{index}"));
}
return list.map(item=>item.get()); // 循环获取结果
'''
).strip(),
},
],
"doc": "https://www.ssssssss.org/magic-api/pages/base/async/",
},
"lambda_expressions": {
"title": "Lambda 表达式",
"summary": "支持现代函数式编程,提供 map、filter、group 等高阶函数。",
"sections": [
{
"heading": "映射(map)",
"code": textwrap.dedent(
'''
var list = [
{sex : 0,name : '小明',age : 19},
{sex : 1,name : '小花',age : 18}
];
var getAge = (age) => age > 18 ? '成人' : '未成年'
// 利用map函数对list进行过滤
return list.map(item => {
age : getAge(item.age),
sex : item.sex == 0 ? '男' : '女',
name : item.name
});
'''
).strip(),
"notes": "支持对象转换和条件判断",
},
{
"heading": "过滤(filter)",
"code": textwrap.dedent(
'''
var list = [
{sex : 0,name : '小明'},
{sex : 1,name : '小花'}
]
// 利用filter函数对list进行过滤
return list.filter(item => item.sex == 0);
'''
).strip(),
"notes": "等价于 SQL 中的 WHERE 子句",
},
{
"heading": "分组(group)",
"code": textwrap.dedent(
'''
var result = [
{ xxx : 1, yyy : 2, value : 11},
{ xxx : 1, yyy : 2, value : 22},
{ xxx : 2, yyy : 2, value : 33}
];
return result.group(item => item.xxx + '_' + item.yyy)
'''
).strip(),
"notes": "支持自定义聚合函数",
},
],
"doc": "https://www.ssssssss.org/magic-api/pages/base/lambda/",
},
"linq": {
"title": "Linq 查询",
"summary": "提供类似 SQL 的查询语法,支持关联、转换、分组等操作。",
"sections": [
{
"heading": "基本语法",
"code": textwrap.dedent(
'''
select
tableAlias.*|[tableAlias.]field[ columnAlias]
[,tableAlias.field2[ columnAlias2][,…]]
from expr[,…] tableAlias
[[left ]join expr tableAlias2 on condition]
[where condition]
[group by tableAlias.field[,...]]
[having condition]
[order by tableAlias.field[asc|desc][,tableAlias.field[asc|desc]]]
[limit expr [offset expr]]
'''
).strip(),
},
{
"heading": "查询示例",
"code": textwrap.dedent(
'''
return select
t.name, sum(t.score) score,
t.*
from results t
where t.status = 1
group by t.name
having count(t.name) > 1
order by score desc
limit 10
'''
).strip(),
},
],
"doc": "https://www.ssssssss.org/magic-api/pages/base/linq/",
},
"mybatis_syntax": {
"title": "MyBatis 动态SQL语法",
"summary": "Magic-API 支持 MyBatis 风格的动态SQL语法,提供强大的条件查询和动态更新能力。",
"sections": [
{
"heading": "if 条件判断",
"description": "使用 <if> 标签进行条件判断,只有当条件成立时才会包含其中的SQL片段。",
"code": textwrap.dedent(
'''
return db.select("""
select * from hrm_org
<if test="params.name != null">
where org_name like concat('%', #{params.name}, '%')
</if>
<if test="params.status != null">
and status = #{params.status}
</if>
""")
'''
).strip(),
"notes": [
"test属性中的变量直接访问,无需额外声明",
"支持JavaScript表达式,如比较运算、逻辑运算等",
"支持字符串拼接函数concat等"
]
},
{
"heading": "elseif / else 条件分支",
"description": "使用 <elseif> 和 <else> 创建条件分支结构。",
"code": textwrap.dedent(
'''
const val = 1
return db.select("""
select api_name from magic_api_info
where
<if test="val == 2">
api_name is not null
</if>
<elseif test="val == 1">
api_name = '测试'
</elseif>
<else>
api_name is null
</else>
""")
'''
).strip(),
"notes": [
"elseif必须紧跟if标签之后",
"else标签不需要test条件",
"支持多层嵌套条件判断"
]
},
{
"heading": "foreach 循环遍历",
"description": "使用 <foreach> 标签遍历集合,生成重复的SQL片段。",
"code": textwrap.dedent(
'''
const idList = ['1', '2', '3']
return db.select("""
select id from magic_api_info
where id in
<foreach collection="idList" open="(" separator="," close=")" item="item">
#{item}
</foreach>
""")
'''
).strip(),
"attributes": {
"collection": "要遍历的集合变量名",
"item": "集合中每个元素的变量名",
"index": "集合中元素的索引变量名(可选)",
"open": "循环开始时插入的字符串",
"close": "循环结束时插入的字符串",
"separator": "元素之间的分隔符"
},
"notes": [
"collection属性指定要遍历的变量",
"支持数组、List等集合类型",
"常用于IN条件和批量插入"
]
},
{
"heading": "set 动态更新",
"description": "使用 <set> 标签动态生成UPDATE语句的SET子句,会自动处理逗号和前缀。",
"code": textwrap.dedent(
'''
var sql = """
update test_data
<set>
<if test="params.name != null">
name = #{params.name},
</if>
<if test="params.content != null">
content = #{params.content},
</if>
</set>
where id = #{params.id}
"""
return db.update(sql, params)
'''
).strip(),
"notes": [
"set标签会自动添加SET关键字",
"自动处理字段间的逗号分隔",
"避免更新语句中出现多余的逗号"
]
},
{
"heading": "where 条件封装",
"description": "使用 <where> 标签自动处理WHERE子句,会自动添加WHERE关键字并处理AND/OR逻辑。",
"code": textwrap.dedent(
'''
return db.select("""
select * from users
<where>
<if test="params.name != null">
and name like concat('%', #{params.name}, '%')
</if>
<if test="params.status != null">
and status = #{params.status}
</if>
</where>
""")
'''
).strip(),
"notes": [
"where标签会自动添加WHERE关键字",
"自动处理第一个AND关键字",
"避免出现空WHERE子句"
]
},
{
"heading": "trim 字符串处理",
"description": "使用 <trim> 标签自定义SQL片段的格式。",
"code": textwrap.dedent(
'''
return db.select("""
select * from users
<trim prefix="WHERE" prefixOverrides="AND |OR ">
<if test="params.name != null">
AND name like concat('%', #{params.name}, '%')
</if>
<if test="params.status != null">
OR status = #{params.status}
</if>
</trim>
""")
'''
).strip(),
"attributes": {
"prefix": "添加的前缀",
"suffix": "添加的后缀",
"prefixOverrides": "移除的前缀",
"suffixOverrides": "移除的后缀"
}
},
{
"heading": "choose / when / otherwise 选择结构",
"description": "使用 <choose> 创建多条件选择结构。",
"code": textwrap.dedent(
'''
return db.select("""
select * from orders
<where>
<choose>
<when test="params.vipUser">
and user_level = 'VIP'
</when>
<when test="params.newUser">
and create_time > date_sub(now(), interval 30 day)
</when>
<otherwise>
and status = 'active'
</otherwise>
</choose>
</where>
""")
'''
).strip(),
"notes": [
"choose内只能有一个otherwise标签",
"when条件按顺序匹配,第一个匹配的执行",
"otherwise是可选的默认分支"
]
}
],
"advanced_features": [
{
"name": "变量绑定",
"description": "使用 #{variable} 进行参数绑定,防止SQL注入",
"example": "where name = #{params.name} and age > #{params.age}"
},
{
"name": "字符串拼接",
"description": "使用 ${variable} 进行字符串拼接(有SQL注入风险)",
"example": "where name like '%${params.name}%'"
},
{
"name": "OGNL表达式",
"description": "支持OGNL表达式语法进行复杂条件判断",
"example": '<if test="params.userList != null and params.userList.size() > 0">'
},
{
"name": "集合操作",
"description": "支持对集合进行size()、isEmpty()等操作",
"example": '<if test="params.ids != null and !params.ids.isEmpty()">'
}
],
"best_practices": [
"优先使用 #{param} 进行参数绑定,避免 ${param} 的SQL注入风险",
"合理使用 <where> 标签避免出现空的WHERE子句",
"使用 <set> 标签简化UPDATE语句的字段设置",
"<foreach> 常用于IN查询和批量插入操作",
"复杂条件建议使用 <choose> 而不是多个 <if> 嵌套",
"注意变量作用域,test属性中的变量要确保存在"
],
"doc": "https://www.ssssssss.org/magic-api/pages/quick/crud/#mybatis%E8%AF%AD%E6%B3%95%E6%94%AF%E6%8C%81"
},
"script_syntax": {
"title": "脚本语法示例",
"description": "Magic-API脚本语言的核心语法示例和最佳实践",
"examples": {
"if_statement": {
"title": "if条件判断",
"description": "if语句的各种使用形式和条件判断规则",
"code": textwrap.dedent('''
/*
if 测试
*/
if(a == 1){
return 1;
}else if(a == 2){
return 2;
}else{
return 0;
}
/*
对于条件判断,特意支持了简写的方式
如 可以直接写
1、if(a)
2、else if(a)
3、while(a)
4、a ? 1 : 0
当a的值是以下情况时为false
null
空集合
空Map
数值 == 0
空字符串(length == 0)
false
其它情况一律视为true
*/
''').strip(),
"notes": [
"支持完整的if-else if-else结构",
"支持条件简写形式",
"false值的判断规则与JavaScript类似",
"支持三元运算符 a ? b : c"
],
"tags": ["条件判断", "控制流", "布尔值"]
},
"exit_statement": {
"title": "exit语句",
"description": "使用exit语句提前终止执行并返回指定结果",
"code": textwrap.dedent('''
if(0){
exit 400,'参数填写有误'
}
// 第一个参数为code,第二个为message,第三个为data,至少要填写一个参数。
exit 200,'success','ok'
''').strip(),
"notes": [
"exit后可以跟1-3个参数:状态码、消息、数据",
"会立即终止脚本执行",
"常用于参数验证失败或错误处理",
"类似于HTTP状态码返回"
],
"tags": ["退出", "错误处理", "状态码"]
},
"type_conversion": {
"title": "类型转换",
"description": "Magic-API支持的三种类型转换方法",
"code": textwrap.dedent('''
var a = 123;
var str = "456.0";
/* 目前转换的办法一共有三种,
1、使用Java相关函数,如Integer.parseInt
2、是使用脚本提供的语法::进行转换,支持::int ::double ::string ::byte ::long ::short ::float ::date
3、使用扩展方法,xxx.asXXX(); 如 a.asInt()
*/
return {
'::string': a::string, // 使用::转换,好处是它是语法级的,不会产生空指针,
'::int' : str::int(0), // 转换失败是使用默认值0,
'ext': a.asString(), // 使用扩展方法转换
'toDate' : '2020-01-01'::date('yyyy-MM-dd'),
"obj::stringify":{"a":a}::stringify
};
''').strip(),
"notes": [
"::语法转换 - 语法级转换,不会产生空指针异常",
"支持默认值 - ::int(0) 在转换失败时使用默认值",
"扩展方法 - asXXX() 方法系列",
"日期转换 - 支持自定义格式化模式"
],
"tags": ["类型转换", "数据类型", "安全转换"]
},
"operators": {
"title": "各类运算符",
"description": "Magic-API支持的完整运算符集合",
"code": textwrap.dedent('''
var a = 123; // 定义int型变量,定义变量只能使用var。var可以省略
var b = 456;
return {
'+': a + b, // 加法
'-': a - b, // 减法
'-a' : -a, // 负数
'*': a * b, // 乘法
'/': a / b, // 除法
'%': a % b, // 取模
'++': a++, // 自增
'--': a--, // 自减
'>': a > b, // 大于
'>=': a >= b, // 大于等于
'<': a < b, // 小于
'<=': a <= b, // 小于等于
'==': a == b, // 等于
'===': a === b, // 严格等于(类型和值都相等)
'!=': a != b, // 不等于
'!==': a !== b, // 严格不等于
'&&': a && b, // 逻辑与
'||': a || b, // 逻辑或
'>>': 8 >> 2, // 右移
'>>>': 8 >>> 2, // 无符号右移
'<<' : 1 << 2, // 左移
'^' : 1 ^ 2, // 异或
'&': 1 & 2, // 按位与
'|': 1 | 2 // 按位或
};
''').strip(),
"notes": [
"支持完整的算术运算符",
"支持比较运算符,包括严格相等",
"支持逻辑运算符,短路求值",
"支持位运算符",
"变量定义使用var关键字"
],
"tags": ["运算符", "算术", "逻辑", "位运算"]
},
"lambda_definition": {
"title": "Lambda表达式定义",
"description": "定义和使用Lambda表达式的各种形式",
"code": textwrap.dedent('''
/*
测试Lambda
*/
var lambda1 = e => e + 1; //单参数单行代码,省略括号,省略{}
var lambda2 = (e) => e +1; //单参数单行代码,不省略括号,省略{} 作用同上
var lambda4 = e => {e + 1};//单参数无返回值,不能省略{}
var lambda5 = e => {return e + 1};//单参数有返回值,省略括号,不省略{}
var lambda6 = (e) => {return e + 1};//单参数有返回值,不省略括号,不省略{},作用同上
var lambda7 = (a,b) => a + b; //多参数单行代码,省略{}
var lambda8 = (a,b) => {return a + b}; //多参数单行代码,有返回值,作用同上
var lambda9 = (a,b) =>{ //多参数多行代码, 无法省略括号和{}
a = a + 1;
return a + b;
};
var v1 = lambda1(1); //返回2
var v2 = lambda2(v1); //返回3
return lambda9(v1,lambda7(v1,v2)); //返回8
''').strip(),
"notes": [
"支持多种Lambda定义语法",
"单行代码可以省略{}",
"多行代码必须使用{}",
"支持单参数和多参数",
"支持有返回值和无返回值"
],
"tags": ["Lambda", "函数式编程", "匿名函数"]
},
"optional_chaining": {
"title": "可选链操作符",
"description": "使用?.操作符安全访问嵌套属性,避免空指针异常",
"code": textwrap.dedent('''
var map = {
a : {
b : 'ok'
},
c : 1
};
// ?. 不会报错,.会报错
return map.a.bbbb?.c + '-' + map.a?.b;
''').strip(),
"notes": [
"?.操作符在属性不存在时返回undefined,不会抛出异常",
".操作符在属性不存在时会抛出NullPointerException",
"适用于安全访问深层嵌套对象",
"与JavaScript的可选链操作符类似"
],
"tags": ["可选链", "安全访问", "空指针"]
},
"spread_operator": {
"title": "扩展运算符",
"description": "使用...运算符展开对象和数组",
"code": textwrap.dedent('''
var map = {
a : 1,
b : 2
};
var list = [1,2,3,4,5];
return {
...map, // 展开Map
c : 3,
d : [...list] // 展开list
};
''').strip(),
"notes": [
"支持展开对象属性",
"支持展开数组元素",
"常用于对象合并和数组复制",
"与ES6扩展运算符语法相同"
],
"tags": ["扩展运算符", "对象展开", "数组展开"]
},
"async_execution": {
"title": "异步执行",
"description": "使用async关键字进行异步操作",
"code": textwrap.dedent('''
var list = [];
for(index in range(1,10)){
// 执行SQL时,为了线程安全,需要把index参数放入lambda参数中。
list.add(async (index)=>db.selectInt('select #{index}'));
}
return list.map(f => f.get());
''').strip(),
"notes": [
"async标记的Lambda会异步执行",
"返回Future对象,需要调用.get()获取结果",
"常用于并发数据库查询",
"线程安全考虑"
],
"tags": ["异步", "并发", "Future", "线程安全"]
},
"java_interaction": {
"title": "与Java交互",
"description": "在Magic-API脚本中导入和使用Java类",
"code": textwrap.dedent('''
import 'java.util.Date' as Date;
import 'java.text.SimpleDateFormat' as SimpleDateFormat;
var now = new Date(); // 创建对象
var df = new SimpleDateFormat('yyyy-MM-dd');
return df.format(now); // 调用方法
''').strip(),
"notes": [
"使用import语句导入Java类",
"支持as关键字设置别名",
"可以创建Java对象实例",
"可以调用Java对象的方法",
"支持Java的所有类和方法"
],
"tags": ["Java集成", "类导入", "对象创建", "方法调用"]
},
"try_catch": {
"title": "异常处理",
"description": "使用try-catch-finally进行异常处理",
"code": textwrap.dedent('''
try{
var c = 1 / 0;
}catch(e){ //不用写类型,只写变量即可
return e.getMessage();
}finally{
return 'finally';
}
// catch 和finally 都可以不写。
return 'ok';
''').strip(),
"notes": [
"catch块中的变量e即为异常对象",
"不需要指定异常类型",
"finally块总是会执行",
"catch和finally都是可选的",
"支持完整的异常处理机制"
],
"tags": ["异常处理", "try-catch", "finally", "错误处理"]
},
"loop_operations": {
"title": "循环操作",
"description": "Magic-API支持的各种循环操作,包括for循环、while循环和函数式循环",
"code": textwrap.dedent('''
// 1. for-in循环List
var list1 = [1,2,3,4,5];
var listSum = 0;
for(val in list1){
listSum = listSum + val;
}
// 2. for-in循环Map
var map1 = {key1: 1, key2: 2, key3: 3};
var mapSum = 0;
var keys = '';
for(key,value in map1){
mapSum = mapSum + value;
keys = keys + key;
}
// 3. 传统for循环
var rangeSum = 0;
for(val in range(0,100)){ // 包括0和100
if(val > 90){
break; // 跳出循环
}
if(val % 3 == 0){
continue; // 进入下一次循环
}
rangeSum = rangeSum + val;
}
// 4. Lambda循环List
var list2 = [1,2,3,4,5,6,7,8,9,10];
var lambdaListSum = 0;
list2.each(it => lambdaListSum += it + 1);
// 5. Lambda循环Map
var map2 = {key1: 1, key2: 2, key3: 3};
var lambdaMapSum = 0;
var lambdaKeys = '';
map2.each((key,value) => {
lambdaKeys += key;
lambdaMapSum += value;
});
// 6. while循环
var index = 0;
var whileSum = 0;
while(index < 100){
whileSum += index++;
}
return {
listSum: listSum,
mapResult: keys + '-' + mapSum,
rangeSum: rangeSum,
lambdaListSum: lambdaListSum,
lambdaMapResult: lambdaKeys + '-' + lambdaMapSum,
whileSum: whileSum
};
''').strip(),
"notes": [
"for-in循环 - 直接遍历集合元素",
"Map循环 - for(key,value in map)同时获取键值",
"range函数 - range(start,end)包括起始和结束值",
"break和continue - 支持跳出和继续循环",
"Lambda循环 - each()方法使用Lambda表达式",
"while循环 - 标准的while条件循环"
],
"tags": ["循环", "for循环", "while循环", "Lambda循环", "集合遍历"]
}
}
},
"full_syntax": {
"title": "完整Magic-Script语法规则",
"description": "Magic-Script编程语言的完整语法规则,专为AI模型编写代码前获取",
"version": "latest",
"language": "magic-script",
"critical_differences": {
"title": "⚠️ 关键差异:Magic-Script ≠ JavaScript",
"alerts": [
{
"level": "danger",
"title": "牢记:Magic-Script 不是 JavaScript",
"content": "Magic-Script 基于 JVM,语法类似 JS 但有重大差异。不要假设 JS 语法在此适用!"
},
{
"level": "danger",
"title": "牢记:Magic-Script 不是 JavaScript",
"content": "Magic-Script 基于 JVM,语法类似 JS 但有重大差异。不要假设 JS 语法在此适用!"
},
{
"level": "warning",
"title": "循环语法差异",
"content": "Magic-Script 仅支持两种 for 循环:\n1. for(index, item in collection) - 遍历集合(可省略 index)\n2. for(i in range(start, end)) - 数值范围循环\n\n⚠️ 不支持 JS 的 for (init; condition; increment) 语法\n✅ 推荐使用 let 而非 var 声明变量"
},
{
"level": "warning",
"title": "无 switch 语法",
"content": "Magic-Script 没有 switch 语句,使用 if-else 替代。"
},
{
"level": "info",
"title": "优先使用箭头函数",
"content": "推荐使用箭头函数语法:`var myFunction = (a, b) => a + b;` 而不是传统函数声明。"
},
{
"level": "info",
"title": "数据类型严格",
"content": "Magic-Script 是强类型语言,支持类型推断,但数字类型有专门的后缀 (123L, 123f, 123m 等)。"
},
{
"level": "info",
"title": "Java 集成特性",
"content": "可以直接调用 Java 类和方法,导入语法为 `import java.lang.System;`。"
}
]
},
"important_notes": [
"🎯 **语法检查**: 编写代码前务必参考此完整语法规则,避免 JS 思维定式",
"🔄 **版本兼容**: 语法特性可能随版本变化,请注意版本标记 (如 1.2.7+, 1.3.0+)",
"🚀 **最佳实践**: 优先使用箭头函数、let 声明、增强的 if/逻辑运算符",
"⚡ **性能考虑**: 数据库操作使用参数化查询避免 SQL 注入",
"🔧 **调试技巧**: 使用 `exit` 语句快速终止脚本进行调试",
"🧭 **核心工作流**: 执行任何变更前,遵循需求洞察→语法对齐→资源定位→实现调试→结果反馈的工具化流程"
],
"sections": {
"keywords": {
"title": "关键字",
"items": [
"var", "if", "else", "for", "in", "continue", "break",
"exit", "try", "catch", "finally", "import", "as", "new",
"true", "false", "null", "async"
]
},
"operators": {
"title": "运算符",
"math": ["+", "-", "*", "/", "%", "++", "--", "+=", "-=", "*=", "/=", "%="],
"comparison": ["<", "<=", ">", ">=", "==", "!=", "===", "!=="],
"logical": ["&&", "||", "!"],
"ternary": ["condition ? expr1 : expr2"],
"other": ["?.", "..."]
},
"data_types": {
"title": "数据类型",
"numeric": {
"byte": "123b",
"short": "123s",
"int": "123",
"long": "123L",
"float": "123f",
"double": "123d",
"BigDecimal": "123m"
},
"boolean": ["true", "false"],
"string": ["'hello'", '"world"', '"""多行文本"""'],
"regex": ["/pattern/gimuy"],
"functions": {
"title": "函数定义",
"arrow_functions": {
"recommended": "优先使用箭头函数",
"syntax": [
"() => expr",
"(p1, p2) => expr",
"(p1, p2) => { statements; return value; }"
],
"examples": [
"var add = (a, b) => a + b;",
"var process = (data) => { return data.map(item => item * 2); };"
],
"note": "🚀 推荐:优先使用箭头函数语法,简洁且避免 this 绑定问题"
},
"traditional_functions": {
"syntax": "function name(params) { statements; }",
"note": "支持传统函数声明,但不推荐优先使用"
}
},
"array": ["[1, 2, 3]"],
"map": ["{k1: v1, k2: v2}", "{[k]: v}"]
},
"type_conversion": {
"title": "类型转换",
"methods": [
"value::type(defaultValue)",
"value.asType(defaultValue)",
"asInt", "asDouble", "asDecimal", "asFloat", "asLong",
"asByte", "asShort", "asString", "asDate(formats...)"
],
"notes": "asDate支持多种格式,数字对象10位秒,13位毫秒"
},
"type_checking": {
"title": "类型判断",
"methods": [
"value.is(type)", "value.isType()",
"isString", "isInt", "isLong", "isDouble", "isFloat",
"isByte", "isBoolean", "isShort", "isDecimal", "isDate",
"isArray", "isList", "isMap", "isCollection"
]
},
"loops": {
"title": "循环",
"syntax": [
"for (index, item in list) { ... }",
"for (value in range(start, end)) { ... }",
"for (key, value in map) { ... }"
]
},
"imports": {
"title": "导入",
"syntax": [
"import 'java.lang.System' as System;", # Java类
"import log;", # 模块
"import log as logger;" # 模块重命名
]
},
"object_creation": {
"title": "对象创建",
"syntax": ["new JavaClass()"]
},
"async": {
"title": "异步",
"syntax": ["async func()", "future.get()"]
},
"enhanced_features": {
"title": "增强特性",
"items": [
"增强if: if(x),x为null、空集合/Map/数组、0、空字符串、false时为false (1.2.7+)",
"增强逻辑运算符: && 和 || 不强制要求布尔类型 (1.3.0+)",
"可选链: a?.b 安全访问属性/方法,避免空指针",
"扩展运算符: ... 展开列表或映射"
]
},
"comments": {
"title": "注释",
"syntax": ["// 单行", "/* 多行 */"]
},
"database": {
"title": "数据库操作 (db对象,默认引入)",
"crud": {
"select": "db.select(sql, params): List<Map>",
"selectInt": "db.selectInt(sql, params): int",
"selectOne": "db.selectOne(sql, params): Map",
"selectValue": "db.selectValue(sql, params): Object",
"update": "db.update(sql, params): int",
"insert": "db.insert(sql, params, id?): Object",
"batchUpdate": "db.batchUpdate(sql, List<Object[]>): int"
},
"pagination": "db.page(sql, limit?, offset?, params?)",
"sql_params": {
"injection": "#{ }: 注入参数(防SQL注入)",
"concat": "${ }: 字符串拼接(慎用,有注入风险)",
"dynamic": "?{condition, expression}: 动态SQL"
},
"datasource": "db.slave.select(...)",
"cache": {
"usage": "db.cache(name, ttl?).select/update/insert(...)",
"delete": "db.deleteCache(name)"
},
"transaction": [
"db.transaction(() => { ... })", # 自动
"tx = db.transaction(); tx.commit(); tx.rollback();" # 手动
],
"column_conversion": ["db.camel()", "db.pascal()", "db.upper()", "db.lower()", "db.normal()"],
"single_table": {
"base": "db.table('name')",
"methods": [
".logic()", ".withBlank()", ".column(col, val?)", ".primary(key, default?)",
".insert(data)", ".batchInsert(list, size?)",
".update(data, updateBlank?)", ".save(data, beforeQuery?)",
".select()", ".page()",
".where().eq/ne/lt/gt/lte/gte/in/notIn/like/notLike(col, val)"
]
},
"mybatis_integration": {
"version": "1.6.0+",
"tags": ["<if>", "<elseif>", "<else>", "<where>", "<foreach>", "<trim>", "<set>"],
"example": """
var sql = '''
select * from users
<where>
<if test="name != null">and name = #{name}</if>
<if test="age != null">and age = #{age}</if>
</where>
''';
var users = db.select(sql, {name: 'a', age: 3});
"""
}
},
"http_response": {
"title": "HTTP响应 (response模块)",
"import": "import response;",
"methods": {
"page": "response.page(total, values): 构建分页响应",
"json": "response.json(value): 返回JSON响应",
"text": "response.text(value): 返回纯文本响应",
"redirect": "response.redirect(url): 重定向",
"download": "response.download(value, filename): 下载文件",
"image": "response.image(value, mimeType): 返回图片响应",
"headers": "response.addHeader/setHeader(key, value)",
"cookies": "response.addCookie/addCookies(key, value, options?)",
"stream": "response.getOutputStream(): 获取ServletOutputStream",
"end": "response.end(): 取消默认json结构,通过其他方式输出结果"
}
},
"http_request": {
"title": "HTTP请求 (request模块)",
"import": "import request;",
"methods": {
"getFile": "request.getFile(name): 获取上传文件(MultipartFile)",
"getFiles": "request.getFiles(name): 获取上传文件列表",
"getValues": "request.getValues(name): 获取同名参数值列表",
"getHeaders": "request.getHeaders(name): 获取同名请求头列表",
"getRequest": "request.get(): 获取MagicHttpServletRequest对象",
"getClientIP": "request.getClientIP(): 获取客户端IP地址"
}
},
"request_parameters": {
"title": "请求参数获取",
"description": "Magic-API自动映射的请求参数变量,无需额外声明即可使用",
"parameters": {
"url_params": {
"title": "URL参数 (Query Parameters)",
"description": "GET请求的URL参数自动映射为同名变量",
"example": "GET /api/user?name=abc&age=49",
"usage": "直接使用变量名: name, age (自动映射)",
"notes": "URL中的查询参数会自动转换为同名变量"
},
"form_params": {
"title": "表单参数 (Form Parameters)",
"description": "POST请求的表单参数自动映射为同名变量",
"example": "POST /api/user\nname=abc&age=49",
"usage": "直接使用变量名: name, age (自动映射)",
"notes": "application/x-www-form-urlencoded格式的参数自动映射"
},
"request_body": {
"title": "请求体参数 (Request Body)",
"description": "JSON或其他格式的请求体映射为body变量",
"example": '{"name": "magic-api", "version": "9.9.9"}',
"usage": "body.name, body.version (通过body对象访问)",
"notes": [
"JSON对象通过body.属性名访问",
"数组或List类型时body为数组,可遍历访问",
"非JSON格式需通过request模块方法获取"
]
},
"path_params": {
"title": "路径参数 (Path Parameters)",
"description": "URL路径中的参数变量",
"example": "/user/{id} -> /user/123",
"usage": "path.id 或 直接使用 id (推荐path.id避免冲突)",
"notes": [
"RESTful风格路径参数自动映射",
"当URL参数与路径参数同名时,优先使用URL参数,可用path.前缀区分",
"如: /user/1?id=2, id=2(来自URL), path.id=1(来自路径)"
]
},
"headers": {
"title": "请求头参数 (Request Headers)",
"description": "所有请求头统一封装为header变量",
"example": "Authorization: Bearer token123",
"usage": "header.authorization 或 header.token",
"notes": "所有请求头字段自动转换为小写,可通过header.字段名访问"
},
"cookies": {
"title": "Cookie参数 (Cookies)",
"description": "所有Cookie统一封装为cookie变量",
"example": "JSESSIONID=abc123",
"usage": "cookie.jsessionid 或 cookie.JSESSIONID",
"notes": "通过cookie.名称访问Cookie值"
},
"session": {
"title": "Session参数 (Session)",
"description": "HttpSession封装为session变量",
"example": "session.userId = 123",
"usage": "session.userId, session.username",
"notes": "通过session.属性名访问Session中的值"
}
},
"important_notes": [
"所有参数变量自动映射,无需额外声明即可直接使用",
"如果脚本自定义变量与参数变量冲突,自定义变量优先级更高",
"复杂参数获取可使用request模块提供的方法",
"文件上传参数需通过request.getFile()等方法获取"
]
},
"java_integration": {
"title": "Java调用",
"spring_beans": [
"import xx.xxx.Service; Service.method();",
"import 'beanName' as service; service.method();"
],
"static_methods": "import xxx.StringUtils; StringUtils.isBlank('');",
"regular_methods": "java.util/java.lang下的类可直接new,其他类需import",
"magic_api_interfaces": "import '@get:/api/x' as x; x();",
"magic_api_functions": "import '@/common/f' as f; f('1');"
},
"object_extensions": {
"title": "对象扩展方法",
"type_conversion": [
"asInt(defaultValue)", "asDouble(defaultValue)", "asDecimal(defaultValue)",
"asFloat(defaultValue)", "asLong(defaultValue)", "asByte(defaultValue)",
"asShort(defaultValue)", "asDate(formats...)", "asString(defaultValue)"
],
"type_checking": [
"is(type)", "isString()", "isInt()", "isLong()", "isDouble()",
"isFloat()", "isByte()", "isBoolean()", "isShort()", "isDecimal()",
"isDate()", "isArray()", "isList()", "isMap()", "isCollection()"
]
},
"coding_style": {
"title": "代码风格",
"rules": [
"{} 包裹代码块",
"; 结尾(通常可省略)",
"类Java/JS缩进",
"支持Java API、range()、Java 8+ Stream API、cn.hutool"
],
"notes": "强类型语言,但支持类型推断"
}
}
},
}
def get_syntax(topic: str) -> Dict[str, Any] | None:
"""获取指定语法主题的详细信息。"""
return SYNTAX_KNOWLEDGE.get(topic)
def get_full_syntax_rules(locale: str = "zh-CN") -> Dict[str, Any]:
"""获取完整的Magic-Script语法规则。
从SYNTAX_KNOWLEDGE中提取full_syntax配置,
返回完整的语法规则供AI模型编写代码前使用。
Args:
locale: 语言设置,默认为zh-CN
Returns:
包含完整语法规则的字典
"""
full_syntax_config = SYNTAX_KNOWLEDGE.get("full_syntax", {})
if not full_syntax_config:
return {}
# 构建返回结果
result = {
"language": full_syntax_config.get("language", "magic-script"),
"version": full_syntax_config.get("version", "latest"),
"description": full_syntax_config.get("description", ""),
"locale": locale,
"critical_differences": full_syntax_config.get("critical_differences", {}),
"important_notes": full_syntax_config.get("important_notes", []),
"sections": full_syntax_config.get("sections", {})
}
return result
def list_syntax_topics() -> List[str]:
"""获取所有可用的语法主题。"""
return list(SYNTAX_KNOWLEDGE.keys())
__all__ = [
"SYNTAX_KNOWLEDGE",
"get_syntax",
"get_full_syntax_rules",
"list_syntax_topics"
]