npx skills add https://github.com/nangohq/skills --skill nango-function-builder使用可重复的模式和验证步骤构建可部署的 Nango 函数(动作和同步)。
如果任务是同步,请在编写代码前阅读 references/syncs.md 并首先说明以下路径之一:
updated_at、modified_since、变更记录端点、游标、页面令牌、偏移量/页码、since_id 或 webhook)无效的同步实现:
saveCheckpoint() 而没有 getCheckpoint()Build deployable Nango functions (actions and syncs) with repeatable patterns and validation steps.
If the task is a sync, read references/syncs.md before writing code and state one of these paths first:
updated_at, modified_since, changed-records endpoint, cursor, page token, offset/page, since_id, or webhook)Invalid sync implementations:
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
syncType: 'incremental' 或 nango.lastSyncDatetrackDeletesStart() / trackDeletesEnd() 与仅变更检查点(modified_after、updated_after、变更记录端点)一起使用。这些请求会忽略未变更的行,因此 trackDeletesEnd() 会错误地删除它们。trackDeletesStart() / trackDeletesEnd()动作:
createAction() 构建references/actions.md同步:
createSync() 构建references/syncs.mdreferences/actions.md 或 references/syncs.md。no nango.yaml)并且你在 Nango 根目录(存在 .nango/)。{integrationId}/actions/ 或 {integrationId}/syncs/ 下创建或更新函数,应用此处的模式和命名规则,然后在 index.ts 中注册它。nango dryrun ... --validate -e dev --no-interactive --auto-confirm 进行验证。nango dryrun ... --save,然后运行 nango generate:tests,接着运行 npm test。nango deploy dev 进行部署。始终需要:
动作特定:
--input 和模拟测试的测试输入 JSON(必需;对于无输入动作使用 {})同步特定:
since_id 或复合模式)如果缺少任何必需的外部值,请在检查仓库和提供者文档后提出有针对性的问题。对于同步,只要提供者支持,就选择检查点加删除策略。如果找不到可行的检查点策略,请在编写完全刷新之前确切说明原因。
此技能仅支持使用 createAction()/createSync() 的 TypeScript 项目。
ls nango.yaml 2>/dev/null && echo "YAML PROJECT DETECTED" || echo "OK - No nango.yaml"
如果看到 YAML PROJECT DETECTED:
在确认 Nango 根目录之前不要创建文件:
ls -la .nango/ 2>/dev/null && pwd && echo "IN NANGO PROJECT ROOT" || echo "NOT in Nango root"
如果看到 NOT in Nango root:
所有文件路径必须相对于 Nango 根目录。在已处于 Nango 根目录时使用额外前缀创建文件将创建嵌套目录,从而破坏构建。
./
|-- .nango/
|-- index.ts
|-- hubspot/
| |-- actions/
| | `-- create-contact.ts
| `-- syncs/
| `-- fetch-contacts.ts
`-- slack/
`-- actions/
`-- post-message.ts
fetch- 前缀,但它是可选的)index.ts 中注册脚本(必需)仅使用副作用导入(无默认/命名导入)。包含 .js 扩展名。
// index.ts
import './github/actions/get-top-contributor.js';
import './github/syncs/fetch-issues.js';
注册不正确的症状:文件编译但看到 No entry points found in index.ts... 或函数从未出现。
createAction() / createSync(),而不是 nango.yaml。import './<path>.js')在 index.ts 中注册每个动作/同步。zod、crypto/node:crypto 和 url/node:url。0;特意设置 retries,特别是对于写入操作。id。checkpoint 模式,首先调用 nango.getCheckpoint(),并在每个页面或批次后调用 nango.saveCheckpoint()。since、updated_after、cursor、page_token、offset、page、since_id 等)时才有效。保存一个而不使用它不是增量同步。syncType: 'incremental' 或 nango.lastSyncDate。nango.paginate(...) + nango.batchSave(...)。当 cursor、link 或 offset 分页适用时,避免手动 while (true) 循环。batchDelete()。deleteRecordsFromPreviousExecutions() 已弃用。对于完全刷新,在获取/保存之前调用 trackDeletesStart(),并且仅在成功完成完整获取/保存后调用 trackDeletesEnd()。trackDeletesStart() / trackDeletesEnd() 与仅变更检查点(modified_after、updated_after、变更记录端点等)结合使用。它们会忽略未变更的行,因此 trackDeletesEnd() 会删除它们。trackDeletesEnd()。.describe() 示例。any;使用内联映射类型。:id / {id});在输入/参数中传递 ID。cursor 加上该 API 主流命名的下一个游标字段(next_cursor、nextCursor 等)。nango.zodValidateInput();否则依赖模式 + nango dryrun --validate。.optional()。null 有意义时才使用 .nullable(),通常是更新时清除;当调用者也可能省略该字段时添加 .optional()。.optional(),显式 null 用 .nullable(),仅当提供者确实两者都做时才使用 .nullish()。.optional(),并将上游 null 规范化为省略,除非 null 很重要。.optional();仅当上游合约证明有必要时才放宽。.nullable() 而不是 z.union([z.null(), T]) 或 z.union([T, z.null()])。null。z.object() 默认剥离未知键。对于提供者直通,使用 z.object({}).passthrough()、z.record(z.unknown()) 或带有最少细化的 z.unknown()。user_id、userId)、名称(channel_name、channelName)、电子邮件(user_email、userEmail)、URL(callback_url、callbackUrl)和时间戳(created_at、createdAt)。映射示例(API 期望不同的参数名):
const InputSchema = z.object({
userId: z.string()
});
const config: ProxyConfiguration = {
endpoint: 'users.info',
params: {
user: input.userId
},
retries: 3
};
如果 API 是 snake_case,则使用 user_id。目标是保持 API 一致性。
必需循环(不要跳过步骤):
nango dryrun ... --validate -e dev --no-interactive --auto-confirm 直到通过。--input '{...}'(对于无输入动作使用 --input '{}')。--checkpoint '{...}'。nango dryrun ... --save -e dev --no-interactive --auto-confirm 以生成 <script-name>.test.json。nango generate:tests,然后运行 npm test。硬性规则:
<script-name>.test.json 视为生成的输出。切勿创建、编辑、重命名或移动它(包括记录的 hash 字段)。--save 重新记录。*.test.json 中硬编码错误负载;对于 404/401/429/超时情况,使用带有 vi.spyOn(...) 的 Vitest 测试。--connection-id。--integration-id <integration-id>。--checkpoint;--lastSyncDate 是遗留模式。nango 不在 PATH 上,使用 npx nango ...。NANGO_CLI_UPGRADE_MODE=ignore。references/actions.mdreferences/syncs.md将函数部署到 Nango 账户中的环境:
nango deploy dev
# 仅部署一个函数
nango deploy --action <action-name> dev
nango deploy --sync <sync-name> dev
如果网页抓取返回不完整的文档(JS 渲染):
--validate 的 dryrun 直到通过,然后运行带 --save 的 dryrun,接着运行 nango generate:tests动作:
references/actions.md 中的动作模式createAction() 包含端点、输入、输出和所需的作用域nango.ActionError--validate -e dev --no-interactive --auto-confirm --input '{...}' 成功<action-name>.test.json 由 nango dryrun ... --save 在 --validate 后生成nango generate:tests 且 npm test 通过同步:
references/syncs.md 中的同步模式.optional(),除非 null 重要nango.getCheckpoint(),并在每个页面或批次后运行 nango.saveCheckpoint()since、updated_after、cursor、page_token、offset、page、since_id 等)modified_after、updated_after、变更记录端点)不使用 trackDeletesStart() / trackDeletesEnd()null,字段使用直通命名或 API 的主流命名nango.paginate(),除非 API 确实无法适应 Nango 的分页器batchDelete();否则完全刷新回退在获取/保存之前使用 trackDeletesStart(),并且仅在成功完成完整获取加保存后使用 trackDeletesEnd()--validate -e dev --no-interactive --auto-confirm 成功<sync-name>.test.json 由 nango dryrun ... --save 在 --validate 后生成nango generate:tests 且 npm test 通过每周安装次数
107
仓库
首次出现
2026年2月12日
安全审计
安装于
opencode106
codex105
gemini-cli104
kimi-cli104
github-copilot104
amp104
saveCheckpoint() without getCheckpoint()syncType: 'incremental' or nango.lastSyncDate in a new synctrackDeletesStart() / trackDeletesEnd() with a changed-only checkpoint (modified_after, updated_after, changed-records endpoint). Those requests omit unchanged rows, so trackDeletesEnd() will falsely delete them.trackDeletesStart() / trackDeletesEnd() in an incremental sync that already has explicit deleted-record eventsAction:
createAction()references/actions.md before writing codeSync:
createSync()references/syncs.md before writing codereferences/actions.md or references/syncs.md.no nango.yaml) and that you are in the Nango root (.nango/ exists).{integrationId}/actions/ or {integrationId}/syncs/, apply the schema and casing rules here, then register it in index.ts.nango dryrun ... --validate -e dev --no-interactive --auto-confirm.nango dryrun ... --save, then nango generate:tests, then npm test.nango deploy dev only when requested.Always:
Action-specific:
--input and mocks (required; use {} for no-input actions)Sync-specific:
since_id, or composite)If any required external values are missing, ask a targeted question after checking the repo and provider docs. For syncs, choose a checkpoint plus deletion strategy whenever the provider supports one. If you cannot find a viable checkpoint strategy, state exactly why before writing a full refresh.
This skill only supports TypeScript projects using createAction()/createSync().
ls nango.yaml 2>/dev/null && echo "YAML PROJECT DETECTED" || echo "OK - No nango.yaml"
If you see YAML PROJECT DETECTED:
Do not create files until you confirm the Nango root:
ls -la .nango/ 2>/dev/null && pwd && echo "IN NANGO PROJECT ROOT" || echo "NOT in Nango root"
If you see NOT in Nango root:
All file paths must be relative to the Nango root. Creating files with extra prefixes while already in the Nango root will create nested directories that break the build.
./
|-- .nango/
|-- index.ts
|-- hubspot/
| |-- actions/
| | `-- create-contact.ts
| `-- syncs/
| `-- fetch-contacts.ts
`-- slack/
`-- actions/
`-- post-message.ts
fetch- prefix, but it's optional)index.ts (required)Use side-effect imports only (no default/named imports). Include the .js extension.
// index.ts
import './github/actions/get-top-contributor.js';
import './github/syncs/fetch-issues.js';
Symptom of incorrect registration: the file compiles but you see No entry points found in index.ts... or the function never appears.
createAction() / createSync(), not nango.yaml.index.ts with side-effect imports (import './<path>.js').zod, crypto/node:crypto, and url/node:url.0; set retries deliberately, especially for writes.id.checkpoint schema, call nango.getCheckpoint() first, and nango.saveCheckpoint() after each page or batch.since, updated_after, cursor, page_token, offset, page, since_id, etc.). Saving one without using it is not incremental sync.syncType: 'incremental' or nango.lastSyncDate.nango.paginate(...) + nango.batchSave(...). Avoid manual while (true) loops when cursor, link, or offset pagination fits.batchDelete() when the provider returns deletions, tombstones, or delete webhooks.deleteRecordsFromPreviousExecutions() is deprecated. For full refresh, call trackDeletesStart() before fetch/save and trackDeletesEnd() only after a successful full fetch/save.trackDeletesStart() / trackDeletesEnd() with changed-only checkpoints (modified_after, updated_after, changed-records endpoints, etc.). They omit unchanged rows, so trackDeletesEnd() would delete them.trackDeletesEnd() only in the run that finishes the full window..describe() examples for IDs, timestamps, enums, and URLs.any; use inline mapping types.:id / {id} in the exposed endpoint); pass IDs in input/params.cursor plus a next-cursor field in the majority casing of that API (next_cursor, nextCursor, etc.).nango.zodValidateInput() only when you need custom validation or logging; otherwise rely on schemas + nango dryrun --validate..optional()..nullable() only when null has meaning, usually clear-on-update; add .optional() when callers may omit the field too..optional() for omitted fields, .nullable() for explicit null, .nullish() only when the provider truly does both..optional() and normalize upstream null to omission unless null matters..optional() for non-required inputs and normalized outputs; widen only when the upstream contract justifies it..nullable() over z.union([z.null(), T]) or z.union([T, z.null()]).null only when the output schema allows it.z.object() strips unknown keys by default. For provider pass-through use z.object({}).passthrough(), z.record(z.unknown()), or z.unknown() with minimal refinements.user_id, userId), names (channel_name, channelName), emails (user_email, userEmail), URLs (callback_url, callbackUrl), and timestamps (created_at, createdAt).Mapping example (API expects a different parameter name):
const InputSchema = z.object({
userId: z.string()
});
const config: ProxyConfiguration = {
endpoint: 'users.info',
params: {
user: input.userId
},
retries: 3
};
If the API is snake_case, use user_id instead. The goal is API consistency.
Required loop (do not skip steps):
nango dryrun ... --validate -e dev --no-interactive --auto-confirm until it passes.--input '{...}' (use --input '{}' for no-input actions).--checkpoint '{...}' when you need to simulate a resumed run.nango dryrun ... --save -e dev --no-interactive --auto-confirm to generate <script-name>.test.json.nango generate:tests, then npm test.Hard rules:
<script-name>.test.json as generated output. Never create, edit, rename, or move it (including recorded hash fields).--save.*.test.json; use a Vitest test with vi.spyOn(...) for 404/401/429/timeout cases.--connection-id.--integration-id <integration-id> when script names overlap across integrations.--checkpoint for new incremental syncs; --lastSyncDate is a legacy pattern.nango is not on PATH, use npx nango ....NANGO_CLI_UPGRADE_MODE=ignore if needed.references/actions.mdreferences/syncs.mdDeploy functions to an environment in your Nango account:
nango deploy dev
# Deploy only one function
nango deploy --action <action-name> dev
nango deploy --sync <sync-name> dev
If web fetching returns incomplete docs (JS-rendered):
--validate until it passes, then run dryrun with --save, then nango generate:testsAction:
references/actions.md was used for the action patterncreateAction() includes endpoint, input, output, and scopes when requirednango.ActionError is used for expected failures--validate -e dev --no-interactive --auto-confirm --input '{...}'<action-name>.test.json was generated by nango dryrun ... --save after --validatenango generate:tests ran and npm test passesSync:
references/syncs.md was used for the sync pattern.optional() unless null mattersnango.getCheckpoint() is read at the start and nango.saveCheckpoint() runs after each page or batchsince, updated_after, cursor, page_token, offset, page, since_id, etc.)modified_after, updated_after, changed-records endpoint) do not use trackDeletesStart() / trackDeletesEnd()null correctly, and fields use passthrough casing or the API's majority casingnango.paginate() is used unless the API truly cannot fit Nango's paginatorbatchDelete() for incremental only when the provider returns explicit deletions; otherwise full-refresh fallback uses trackDeletesStart() before fetch/save and trackDeletesEnd() only after a successful full fetch plus save--validate -e dev --no-interactive --auto-confirm<sync-name>.test.json was generated by nango dryrun ... --save after --validatenango generate:tests ran and npm test passesWeekly Installs
107
Repository
First Seen
Feb 12, 2026
Security Audits
Installed on
opencode106
codex105
gemini-cli104
kimi-cli104
github-copilot104
amp104
Skills CLI 使用指南:AI Agent 技能包管理器安装与管理教程
43,100 周安装
专业财务计算器套件 - Python贷款、投资、退休、NPV/IRR计算与蒙特卡洛模拟
263 周安装
MiniMax API 使用指南:AI 聊天补全、文本转语音、视频生成
266 周安装
Azure Cosmos DB 最佳实践指南:60+条性能优化规则与SDK模式详解
266 周安装
生物医学搜索工具:一键查询PubMed、临床试验、药物标签等数据库
267 周安装
Chrome扩展UI/UX设计指南:Manifest V3最佳实践与42条规则
272 周安装
Next.js数据获取完整指南:App Router服务器/客户端组件、缓存策略与SWR集成
268 周安装