关于 salla-app-functions-validate
用于验证 Salla App Functions 的技能,规定保存前后的检查与修复循环。它面向需要在发布前核对触发器包装、TypeScript 类型、API 模式和演示店运行行为的开发者。
主要功能
- 01匹配触发器模板包装行
- 02依据触发器声明进行类型检查
- 03按 OpenAPI 验证 Admin API 调用
- 04在演示预览中运行已保存函数
- 05修复后重复保存和检查
适用场景
- 01在发布前发现处理器类型错误
- 02核验 API 调用的请求与响应结构
- 03使用演示店数据检查函数行为
- 04修改代码后重新验证函数
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sallaapp/ salla-partners-agent-kit --skill salla-app-functions-validate安装后在 Claude Code 中输入/salla-app-functions-validate确认已加载。
详细介绍
App Functions — 保存前验证
成功执行 save 是验证的开始,而不是结束。 salla_functions action=save 会在包装函数的首行和末行匹配后返回 200;它不会对函数主体进行类型检查或运行,因此 200 ≠ 函数正确。将**每次 salla_functions action=save**都视为启动一个完整闭环的信号:验证 → 修复 → 再次执行 save → 再次验证,直到全部通过。处理程序若类型检查失败或在运行时出错,会在保存后、部署到演示商店时才暴露。
闭环(每一步如下):(1) 包装函数的首行和末行与模板匹配 → (2) 使用触发器的 .d.ts,按编辑器的标准运行 TypeScript 编译器(非严格模式,忽略未使用的 TS6133)→ (3) 每次对外发起的 Admin API 调用,其请求和响应都通过对应 OpenAPI 文档的验证 → (4) 在演示商店上通过 salla_functions action=preview 运行且无错误(→ salla-app-functions-test)→ 修复所有失败项,再次执行 save 并重跑闭环。步骤 1–2 是保存前唯一的安全保障;每次保存前都要运行。
将凭据保存在 App Settings 中(通过 context.settings 读取),不要放在已保存的源码中——App Functions 通常会调用外部服务,但密钥、令牌和 API 密钥应存放在设置中。令牌/OAuth 处理 → salla-app-auth;Webhook 签名和幂等性 → salla-webhooks。
1. 严格匹配模板包装函数(STRICT)
包装函数由触发器固定,包括其首行(函数签名)和末行(函数定义的结束行)。从 salla_functions action=get 复制包装函数(其 template),并且只编辑主体:保留 context 参数名称、参数类型、返回类型以及结束行,且必须与给出的内容完全一致。将所有代码都放在主体内部——每个 const / let / function / import / class 都必须位于首行和末行之间(将常量或辅助函数提到外部是最常见的出错原因)。
save 会获取模板,并拒绝首行或末行与模板不一致的 content,同时返回预期的行。content 是整个函数(完整包装函数的字符串),而不仅是主体。保存时不会检查主体——这正是步骤 2 中本地 tsc 检查的用途。
2. 使用触发器的类型进行类型检查(与编辑器保持一致)
Portal 编辑器使用 Monaco 的 TypeScript worker(typescript 编译器)进行验证:它通过 addExtraLib 加载触发器的 .d.ts(config.types),使用非严格的默认编译器选项,并忽略 TS6133(已声明但未使用)。请采用同样的标准,避免比实际阻止保存的要求更严格——使用相同的编译器、类型和宽松规则进行验证。
types(来自 action=get)是 .d.ts URL 列表——也就是编辑器加载的确切库。将每个文件下载到处理程序所在目录旁——只获取此触发器的 action=get 返回的 URL(不要获取任意或用户提供的 URL),并使用真实的 .d.ts,不要手写模拟文件:
curl -sSL "https://…/shipments.d.ts" -o salla-globals.d.ts # one per types URL
将完整包装函数放入 handler.ts,然后按照编辑器的标准进行类型检查——非严格模式(Monaco 默认设置),不生成输出,并修复除 TS6133(未使用)以外的所有错误,编辑器会忽略该错误:
# Editor's bar: non-strict, ignores unused (TS6133)
npx -y -p typescript tsc --noEmit --skipLibCheck salla-globals.d.ts handler.ts
可选的更严格超集: --strict 能发现更多问题,但编辑器的标准是非严格模式且忽略未使用项(TS6133)。只有在你选择采用高于编辑器的标准时,才需在保存前解决 --strict 检查发现的问题;这不是阻止保存的要求。
npx -y -p typescript tsc --noEmit --strict --skipLibCheck salla-globals.d.ts handler.ts # optional, stricter than the editor
如果无法访问某个 types URL,请重试,或从 action=get 重新获取。手写模拟文件是最后手段,且只能针对一个触发器设计——以下示例针对发货,因此请将上下文类型改为与你的触发器匹配的类型,并调整 payload 以符合触发器要求;首先要依据该触发器的 types 确认真实结构:
// ILLUSTRATIVE fallback — verify the exact shape from the trigger's `types` (action=get).
declare class Resp {
static success(): Resp;
static error(): Resp;
setStatus(status: number): Resp;
setMessage(message: string): Resp;
setData(data: Record<string, unknown>): Resp;
}
declare type Shipments = {
merchant?: { id?: string | number };
payload?: {
event?: string;
created_at?: string;
data?: Record<string, unknown>;
};
settings?: Record<string, unknown>;
};
检查关卡:“包装函数的首行和末行与模板匹配,所有代码都位于包装函数内部,并且针对触发器的 types 运行 tsc --noEmit 后,按照编辑器的标准(非严格模式,忽略 TS6133)编译通过?”→ 步骤 3。
3. 根据文档中的架构验证出站 Admin API 调用
步骤 1–2 涵盖了处理程序的结构;本步骤则对处理程序发出的 Admin API 调用进行完整验证。当函数调用有文档说明的端点时,应根据该端点的 OpenAPI 架构验证请求正文/参数以及解析后的响应。Salla 的文档页面(docs.salla.dev/<id>.md)包含完整的 OpenAPI 3.x 定义块(路径、components 架构、类型、枚举、required)。
对于每次调用,都按照 salla-api-core 中的规范流程执行读取文档中的 OpenAPI → 按要求构建 → 验证 → 修复 → 重试:查找端点的文档 ID(→ salla-docs),根据架构中的 required/类型/枚举检查请求和解析后的响应,修复所有不匹配之处,并重新运行,直到验证通过。此处不再复述该流程,该流程由 salla-api-core 负责。
检查关卡:“每个有文档说明的 Admin API 调用,其请求和解析后的响应都能通过对应端点的 OpenAPI 架构验证吗?”→ 步骤 4。
4. 在演示商店上运行已保存的函数
tsc 和架构检查通过,并不能证明函数能正确处理真实数据——先执行 save,然后在演示商店上运行 salla_functions action=preview,端到端测试处理程序(→ salla-app-functions-test)。如果预览失败或返回结果不正确,请修复正文,重新执行 save,并重新运行步骤 1–4,直到预览通过。
检查关卡:“Wrapper、tsc 和每个 Admin API 调用的架构检查都通过,并且 action=preview 在演示商店上运行正常吗?”→ salla-app-functions-release。