building-nango-functions-locally

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Build Nango Functions Locally

本地构建Nango Functions

Build deployable Nango actions and syncs in a checked-out Nango project with the local CLI validation and test workflow.
在已检出的Nango项目中,通过本地CLI验证和测试工作流构建可部署的Nango action和sync。

When to use

适用场景

  • User wants to build or modify a Nango function
  • User wants to build an action in Nango
  • User wants to build a sync in Nango
  • 用户需要构建或修改Nango函数
  • 用户需要在Nango中构建action
  • 用户需要在Nango中构建sync

Sync Strategy Gate (required before writing code)

同步策略门槛(编写代码前必须完成)

If the task is a sync, read
references/syncs.md
before writing code and state one of these paths first:
  • Checkpoint plan:
    • change source (
      updated_at
      ,
      modified_since
      , changed-records endpoint, cursor, page token, offset/page,
      since_id
      , or webhook)
    • checkpoint schema
    • how the checkpoint changes the provider request or resume state
    • whether the request still walks the full dataset or returns changed rows only
    • delete strategy
  • Full refresh blocker:
    • exact provider limitation from the docs or sample payloads
    • why checkpoints cannot work here
Invalid sync implementations:
  • full refresh because it is simpler
  • saveCheckpoint()
    without
    getCheckpoint()
  • reading or saving a checkpoint without using it in request params or pagination state
  • using
    syncType: 'incremental'
    or
    nango.lastSyncDate
    in a new sync
  • using
    trackDeletesStart()
    /
    trackDeletesEnd()
    with a changed-only checkpoint (
    modified_after
    ,
    updated_after
    , changed-records endpoint). Those requests omit unchanged rows, so
    trackDeletesEnd()
    will falsely delete them.
  • using
    trackDeletesStart()
    /
    trackDeletesEnd()
    in an incremental sync that already has explicit deleted-record events
如果当前任务是开发sync,请先阅读
references/syncs.md
,并优先明确以下两种路径之一:
  • 检查点方案:
    • 变更源(
      updated_at
      modified_since
      、变更记录端点、cursor、page token、offset/page、
      since_id
      或webhook)
    • 检查点schema
    • 检查点如何修改provider请求或恢复状态
    • 请求是遍历全量数据集还是仅返回变更行
    • 删除策略
  • 全量刷新阻塞说明:
    • 来自文档或示例payload的明确provider限制
    • 检查点无法生效的原因
无效的sync实现:
  • 仅因为更简单就使用全量刷新
  • 只调用
    saveCheckpoint()
    但不调用
    getCheckpoint()
  • 读取或保存检查点,但未在请求参数或分页状态中使用
  • 新sync中使用
    syncType: 'incremental'
    nango.lastSyncDate
  • 配合仅返回变更的检查点(
    modified_after
    updated_after
    、变更记录端点)使用
    trackDeletesStart()
    /
    trackDeletesEnd()
    :这类请求会忽略未变更的行,导致
    trackDeletesEnd()
    误删这些数据
  • 在已经有显式删除记录事件的增量sync中使用
    trackDeletesStart()
    /
    trackDeletesEnd()

Choose the Path

选择开发路径

Action:
  • One-time request, user-triggered, built with
    createAction()
  • Read
    references/actions.md
    before writing code
Sync:
  • Scheduled or webhook-driven cache updates built with
    createSync()
  • Complete the Sync Strategy Gate first
  • Read
    references/syncs.md
    before writing code
Action:
  • 单次请求、用户触发,使用
    createAction()
    构建
  • 编写代码前请阅读
    references/actions.md
Sync:
  • 定时或webhook驱动的缓存更新,使用
    createSync()
    构建
  • 优先完成同步策略门槛校验
  • 编写代码前请阅读
    references/syncs.md

Required Inputs (Ask User if Missing)

所需输入(缺失时请询问用户)

Always:
  • Integration ID (provider name)
  • Connection ID (for validation or dryrun)
  • Script/function name (kebab-case)
  • API reference URL or sample response
Action-specific:
  • Use case summary
  • Input parameters
  • Output fields
  • Metadata JSON if required
  • Test input JSON for validation/dryrun (required; use
    {}
    for no-input actions)
Sync-specific:
  • Model name (singular, PascalCase)
  • Frequency (every hour, every 5 minutes, etc.)
  • Checkpoint schema (timestamp, cursor, page token, offset/page,
    since_id
    , or composite)
  • How the checkpoint changes the provider request or resume state
  • Delete strategy (deleted-record endpoint/webhook, or why full refresh is required)
  • If proposing a full refresh, the exact provider limitation that blocks checkpoints from the docs/sample response
  • Metadata JSON if required (team_id, workspace_id)
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.
通用要求:
  • 集成ID(provider名称)
  • 连接ID(用于验证或dryrun)
  • 脚本/函数名称(kebab-case格式)
  • API参考文档链接或示例响应
Action专属要求:
  • 使用场景摘要
  • 输入参数
  • 输出字段
  • 所需的Metadata JSON
  • 用于验证/dryrun的测试输入JSON(必填,无输入的action使用
    {}
Sync专属要求:
  • 模型名称(单数,PascalCase格式)
  • 运行频率(每小时、每5分钟等)
  • 检查点schema(timestamp、cursor、page token、offset/page、
    since_id
    或复合类型)
  • 检查点如何修改provider请求或恢复状态
  • 删除策略(删除记录端点/webhook,或需要全量刷新的原因)
  • 如果计划使用全量刷新,需提供来自文档/示例响应的、明确阻塞检查点使用的provider限制
  • 所需的Metadata JSON(team_id、workspace_id等)
如果缺少任何必填的外部值,请先检查仓库和provider文档,再针对性询问用户。对于sync,只要provider支持,就优先选择检查点加删除策略。如果找不到可行的检查点策略,在编写全量刷新逻辑前请明确说明原因。

Non-Negotiable Rules

不可违反的规则

Shared platform constraints

共享平台约束

  • Nango functions use
    createAction()
    /
    createSync()
    .
  • You cannot add arbitrary packages. Use relative imports only when the chosen workflow supports them; built-ins include
    zod
    ,
    crypto
    /
    node:crypto
    , and
    url
    /
    node:url
    .
  • Use the Nango HTTP API for connection lookup, credentials, and proxy calls outside function code. Do not invent CLI token or connection commands.
  • Add an API doc link comment above each provider call.
  • Action outputs cannot exceed 2MB.
  • HTTP retries default to
    0
    ; set
    retries
    deliberately, especially for writes.
  • Nango函数必须使用
    createAction()
    /
    createSync()
  • 不能随意添加依赖包。仅在所选工作流支持时使用相对导入;内置依赖包括
    zod
    crypto
    /
    node:crypto
    url
    /
    node:url
  • 函数代码外的连接查询、凭证获取、代理调用需使用Nango HTTP API,不要自行创建CLI token或连接命令
  • 每个provider调用上方都要添加API文档链接注释
  • Action输出不能超过2MB
  • HTTP重试默认值为
    0
    ,请显式设置
    retries
    值,写操作尤其需要注意

Sync rules

Sync规则

  • Sync records need a stable string
    id
    .
  • New syncs should define a
    checkpoint
    schema, call
    nango.getCheckpoint()
    first, and
    nango.saveCheckpoint()
    after each page or batch.
  • A checkpoint is valid only if it changes the request or resume state (
    since
    ,
    updated_after
    ,
    cursor
    ,
    page_token
    ,
    offset
    ,
    page
    ,
    since_id
    , etc.). Saving one without using it is not incremental sync.
  • New syncs must not use
    syncType: 'incremental'
    or
    nango.lastSyncDate
    .
  • Default to
    nango.paginate(...)
    +
    nango.batchSave(...)
    . Avoid manual
    while (true)
    loops when
    cursor
    ,
    link
    , or
    offset
    pagination fits.
  • Prefer
    batchDelete()
    when the provider returns deletions, tombstones, or delete webhooks.
  • Use full refresh only if the provider cannot return changes, deletions, or resume state, or if the dataset is tiny.
  • For full refresh, cite the exact provider limitation from docs or payloads. "It is easier" is not enough.
  • deleteRecordsFromPreviousExecutions()
    is deprecated. For full refresh, call
    trackDeletesStart()
    before fetch/save and
    trackDeletesEnd()
    only after a successful full fetch/save.
  • Never combine
    trackDeletesStart()
    /
    trackDeletesEnd()
    with changed-only checkpoints (
    modified_after
    ,
    updated_after
    , changed-records endpoints, etc.). They omit unchanged rows, so
    trackDeletesEnd()
    would delete them.
  • Checkpointed full refreshes are still full refreshes. Call
    trackDeletesEnd()
    only in the run that finishes the full window.
  • Sync记录需要有稳定的字符串类型
    id
  • 新sync需要定义
    checkpoint
    schema,首先调用
    nango.getCheckpoint()
    ,每处理完一页或一批数据后调用
    nango.saveCheckpoint()
  • 只有当检查点会修改请求或恢复状态(
    since
    updated_after
    cursor
    page_token
    offset
    page
    since_id
    等)时才有效,只保存不使用不属于增量同步
  • 新sync禁止使用
    syncType: 'incremental'
    nango.lastSyncDate
  • 优先使用
    nango.paginate(...)
    +
    nango.batchSave(...)
    ,如果
    cursor
    link
    offset
    分页适配,避免手动编写
    while (true)
    循环
  • 当provider返回删除记录、逻辑删除标记或删除webhook时,优先使用
    batchDelete()
  • 仅当provider无法返回变更、删除数据或恢复状态,或数据集极小时才使用全量刷新
  • 使用全量刷新时,需要引用来自文档或payload的明确provider限制,「更简单」不能作为理由
  • deleteRecordsFromPreviousExecutions()
    已废弃。全量刷新场景下,在拉取/保存数据前调用
    trackDeletesStart()
    ,仅在全量拉取/保存成功后调用
    trackDeletesEnd()
  • 禁止配合仅返回变更的检查点(
    modified_after
    updated_after
    、变更记录端点等)使用
    trackDeletesStart()
    /
    trackDeletesEnd()
    :这类请求会忽略未变更的行,导致
    trackDeletesEnd()
    误删这些数据
  • 带检查点的全量刷新仍然属于全量刷新,仅在完成全量窗口的运行中调用
    trackDeletesEnd()

Conventions

开发规范

  • Match field casing to the external API. Passthrough fields keep provider casing; non-passthrough fields should use the majority casing of that API.
  • Prefer explicit field names.
  • Add
    .describe()
    examples for IDs, timestamps, enums, and URLs.
  • Avoid
    any
    ; use inline mapping types.
  • Prefer static Nango endpoint paths (avoid
    :id
    /
    {id}
    in the exposed endpoint); pass IDs in input or params.
  • List actions should expose
    cursor
    plus a next-cursor field in the majority casing of that API (
    next_cursor
    ,
    nextCursor
    , etc.).
  • Use
    nango.zodValidateInput()
    only when you need custom validation or logging; otherwise rely on schemas plus the chosen validation workflow.
  • 字段大小写要与外部API保持一致:透传字段保留provider的大小写;非透传字段使用对应API的主流大小写规范
  • 优先使用含义明确的字段名
  • 为ID、时间戳、枚举、URL添加
    .describe()
    示例
  • 避免使用
    any
    ,使用内联映射类型
  • 优先使用静态Nango端点路径(暴露的端点中避免使用
    :id
    /
    {id}
    ),通过输入或参数传递ID
  • 列表类action需要暴露
    cursor
    以及对应API主流大小写格式的下一页游标字段(
    next_cursor
    nextCursor
    等)
  • 仅当需要自定义验证或日志时使用
    nango.zodValidateInput()
    ,其他情况下依赖schema和所选验证工作流

Schema Semantics

Schema语义规范

  • Default non-required inputs to
    .optional()
    .
  • Use
    .nullable()
    only when
    null
    has meaning, usually clear-on-update; add
    .optional()
    when callers may omit the field too.
  • Raw provider schemas should match the provider:
    .optional()
    for omitted fields,
    .nullable()
    for explicit
    null
    ,
    .nullish()
    only when the provider truly does both.
  • Final action outputs and normalized sync models should prefer
    .optional()
    and normalize upstream
    null
    to omission unless
    null
    matters.
  • Default generated schemas to
    .optional()
    for non-required inputs and normalized outputs; widen only when the upstream contract justifies it.
  • Prefer
    .nullable()
    over
    z.union([z.null(), T])
    or
    z.union([T, z.null()])
    .
  • Return
    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.
  • 非必填输入默认添加
    .optional()
  • 仅当
    null
    有明确含义时(通常是更新时清空字段)使用
    .nullable()
    ;如果调用方可能省略该字段,同时添加
    .optional()
  • 原始provider schema要与provider行为匹配:省略的字段用
    .optional()
    ,显式返回
    null
    的字段用
    .nullable()
    ,仅当provider确实会同时返回两种情况时使用
    .nullish()
  • 最终的action输出和标准化的sync模型优先使用
    .optional()
    ,将上游
    null
    标准化为省略该字段,除非
    null
    有明确业务含义
  • 生成的schema默认对非必填输入和标准化输出使用
    .optional()
    ,仅当上游契约有明确要求时放宽限制
  • 优先使用
    .nullable()
    而非
    z.union([z.null(), T])
    z.union([T, z.null()])
  • 仅当输出schema允许时才返回
    null
  • z.object()
    默认会移除未知键,provider透传场景下使用
    z.object({}).passthrough()
    z.record(z.unknown())
    或带最小化校验的
    z.unknown()

Field Naming and Casing Rules

字段命名与大小写规则

  • Use explicit suffixes in the API's majority casing: IDs (
    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):
typescript
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.
  • 使用对应API主流大小写格式的明确后缀:ID(
    user_id
    userId
    )、名称(
    channel_name
    channelName
    )、邮箱(
    user_email
    userEmail
    )、URL(
    callback_url
    callbackUrl
    )、时间戳(
    created_at
    createdAt
映射示例(API期望的参数名与输入字段名不同):
typescript
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一致性。

References

参考资料

  • Action patterns, CRUD examples, metadata usage, and ActionError examples:
    references/actions.md
  • Sync patterns, concrete checkpoint examples, delete strategies, and full refresh fallback:
    references/syncs.md
  • Action模式、CRUD示例、Metadata用法、ActionError示例:
    references/actions.md
  • Sync模式、具体检查点示例、删除策略、全量刷新 fallback:
    references/syncs.md

Useful Nango docs (quick links)

实用Nango文档(快速链接)

When API Docs Do Not Render

API文档无法正常渲染时的处理

If web fetching returns incomplete docs (JS-rendered):
  • Ask the user for a sample response
  • Use existing Nango actions or syncs in the workspace as a pattern when they exist
  • Use the skill-specific validation or dryrun workflow until it passes
如果网页抓取返回的文档不完整(JS渲染的内容):
  • 请用户提供示例响应
  • 如果工作区已有可用的Nango action或sync,可以参考其模式
  • 使用对应技能的验证或dryrun工作流直到通过

Workflow (required)

工作流(必须执行)

  1. Decide whether this is an action or a sync.
  2. Read the matching reference file:
    references/actions.md
    or
    references/syncs.md
    .
  3. For syncs, inspect provider docs or payloads for checkpoints and deletes, decide whether the endpoint returns full data or changed rows, and complete the Sync Strategy Gate.
  4. Gather required inputs and external values. For connection lookup, credentials, or discovery, use the Nango HTTP API.
  5. Confirm this is a Zero YAML TypeScript project (
    no nango.yaml
    ) and that you are in the Nango root (
    .nango/
    exists).
  6. Create or update the function under
    {integrationId}/actions/
    or
    {integrationId}/syncs/
    , apply the shared schema and casing rules, then register it in
    index.ts
    .
  7. Validate with
    nango dryrun ... --validate -e dev --no-interactive --auto-confirm
    .
  8. If validation cannot pass, stop and report the missing external state or inputs.
  9. After validation passes, run
    nango dryrun ... --save
    , then
    nango generate:tests
    , then
    npm test
    .
  10. Deploy with
    nango deploy dev
    only when requested.
  1. 确定开发类型是action还是sync
  2. 阅读对应的参考文档:
    references/actions.md
    references/syncs.md
  3. 对于sync,查阅provider文档或payload确认检查点和删除逻辑,确定端点返回全量数据还是变更行,完成同步策略门槛校验
  4. 收集所需输入和外部值,连接查询、凭证获取或发现逻辑使用Nango HTTP API
  5. 确认当前是Zero YAML TypeScript项目(无
    nango.yaml
    ),且处于Nango根目录(存在
    .nango/
    文件夹)
  6. {integrationId}/actions/
    {integrationId}/syncs/
    下创建或更新函数,遵循共享schema和大小写规则,然后在
    index.ts
    中注册
  7. 使用
    nango dryrun ... --validate -e dev --no-interactive --auto-confirm
    进行验证
  8. 如果验证无法通过,停止并上报缺失的外部状态或输入
  9. 验证通过后,运行
    nango dryrun ... --save
    ,然后运行
    nango generate:tests
    ,再运行
    npm test
  10. 仅当用户要求时,使用
    nango deploy dev
    部署

Preconditions (Do Before Writing Code)

前置条件(编写代码前完成)

Confirm TypeScript Project (No
nango.yaml
)

确认是TypeScript项目(无
nango.yaml

This skill only supports TypeScript projects using
createAction()
/
createSync()
.
bash
ls nango.yaml 2>/dev/null && echo "YAML PROJECT DETECTED" || echo "OK - No nango.yaml"
If you see
YAML PROJECT DETECTED
:
  • Stop immediately.
  • Tell the user to upgrade to the TypeScript format first.
  • Do not attempt to mix YAML and TypeScript.
本技能仅支持使用
createAction()
/
createSync()
的TypeScript项目
bash
ls nango.yaml 2>/dev/null && echo "YAML PROJECT DETECTED" || echo "OK - No nango.yaml"
如果输出
YAML PROJECT DETECTED
  • 立即停止操作
  • 告知用户需要先升级到TypeScript格式
  • 不要尝试混合使用YAML和TypeScript

Verify Nango Project Root

验证Nango项目根目录

Do not create files until you confirm the Nango root:
bash
ls -la .nango/ 2>/dev/null && pwd && echo "IN NANGO PROJECT ROOT" || echo "NOT in Nango root"
If you see
NOT in Nango root
:
  • cd
    into the directory that contains
    .nango/
  • Re-run the check
  • Do not use absolute paths as a workaround
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根目录前不要创建文件:
bash
ls -la .nango/ 2>/dev/null && pwd && echo "IN NANGO PROJECT ROOT" || echo "NOT in Nango root"
如果输出
NOT in Nango root
  • cd
    到包含
    .nango/
    的目录
  • 重新执行校验
  • 不要使用绝对路径作为变通方案
所有文件路径必须是相对于Nango根目录的相对路径。如果已经在Nango根目录下却添加额外路径前缀,会创建嵌套目录导致构建失败。

Project Structure and Naming

项目结构与命名规范

text
./
|-- .nango/
|-- index.ts
|-- hubspot/
|   |-- actions/
|   |   `-- create-contact.ts
|   `-- syncs/
|       `-- fetch-contacts.ts
`-- slack/
    `-- actions/
        `-- post-message.ts
  • Provider directories: lowercase (
    hubspot
    ,
    slack
    )
  • Action files: kebab-case (
    create-contact.ts
    )
  • Sync files: kebab-case (many teams use a
    fetch-
    prefix, but it is optional)
  • One function per file
  • All actions and syncs must be imported in
    index.ts
text
./
|-- .nango/
|-- index.ts
|-- hubspot/
|   |-- actions/
|   |   `-- create-contact.ts
|   `-- syncs/
|       `-- fetch-contacts.ts
`-- slack/
    `-- actions/
        `-- post-message.ts
  • Provider目录:全小写(
    hubspot
    slack
  • Action文件:kebab-case格式(
    create-contact.ts
  • Sync文件:kebab-case格式(很多团队会使用
    fetch-
    前缀,非强制)
  • 每个文件仅包含一个函数
  • 所有action和sync都必须在
    index.ts
    中导入

Register scripts in
index.ts
(required)

index.ts
中注册脚本(必填)

Use side-effect imports only. Include the
.js
extension.
typescript
// 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.
仅使用副作用导入,包含
.js
后缀
typescript
// index.ts
import './github/actions/get-top-contributor.js';
import './github/syncs/fetch-issues.js';
注册错误的表现:文件编译成功,但提示
No entry points found in index.ts...
或函数始终不显示

Dryrun, Mocks, and Tests (required)

Dryrun、Mock与测试(必须执行)

Required loop:
  1. Run
    nango dryrun ... --validate -e dev --no-interactive --auto-confirm
    until it passes.
  2. Actions: always pass
    --input '{...}'
    (use
    --input '{}'
    for no-input actions).
  3. Syncs: use
    --checkpoint '{...}'
    when you need to simulate a resumed run.
  4. If validation cannot pass, stop and state the missing external state or inputs required.
  5. After validation passes, run
    nango dryrun ... --save -e dev --no-interactive --auto-confirm
    to generate
    <script-name>.test.json
    .
  6. Run
    nango generate:tests
    , then
    npm test
    .
Hard rules:
  • Treat
    <script-name>.test.json
    as generated output. Never create, edit, rename, or move it.
  • If mocks are wrong or stale, fix the code and re-record with
    --save
    .
  • Do not hard-code error payloads in
    *.test.json
    ; use a Vitest test with
    vi.spyOn(...)
    for 404, 401, 429, or timeout cases.
  • Connection ID is the second positional argument; do not use
    --connection-id
    .
  • Use
    --integration-id <integration-id>
    when script names overlap across integrations.
  • Prefer
    --checkpoint
    for new incremental syncs;
    --lastSyncDate
    is a legacy pattern.
  • If
    nango
    is not on
    PATH
    , use
    npx nango ...
    .
  • CLI upgrade prompts can block automation; set
    NANGO_CLI_UPGRADE_MODE=ignore
    if needed.
必填循环流程:
  1. 运行
    nango dryrun ... --validate -e dev --no-interactive --auto-confirm
    直到通过
  2. Action:必须传入
    --input '{...}'
    (无输入的action使用
    --input '{}'
  3. Sync:需要模拟恢复运行时使用
    --checkpoint '{...}'
  4. 如果验证无法通过,停止并说明所需的缺失外部状态或输入
  5. 验证通过后,运行
    nango dryrun ... --save -e dev --no-interactive --auto-confirm
    生成
    <script-name>.test.json
  6. 运行
    nango generate:tests
    ,然后运行
    npm test
硬性规则:
  • <script-name>.test.json
    视为生成产物,永远不要手动创建、编辑、重命名或移动
  • 如果mock错误或过时,修复代码后使用
    --save
    重新录制
  • 不要在
    *.test.json
    中硬编码错误payload,404、401、429或超时场景使用带
    vi.spyOn(...)
    的Vitest测试
  • 连接ID是第二个位置参数,不要使用
    --connection-id
  • 不同集成的脚本名称重复时使用
    --integration-id <integration-id>
  • 新增量sync优先使用
    --checkpoint
    --lastSyncDate
    是旧模式
  • 如果
    nango
    不在
    PATH
    中,使用
    npx nango ...
  • CLI升级提示会阻塞自动化流程,必要时设置
    NANGO_CLI_UPGRADE_MODE=ignore

Deploy (Optional)

部署(可选)

Deploy functions to an environment in your Nango account:
bash
nango deploy dev
将函数部署到Nango账号的指定环境:
bash
nango deploy dev

Deploy only one function

仅部署单个函数

nango deploy --action <action-name> dev nango deploy --sync <sync-name> dev

Reference: https://nango.dev/docs/implementation-guides/use-cases/actions/implement-an-action
nango deploy --action <action-name> dev nango deploy --sync <sync-name> dev

参考:https://nango.dev/docs/implementation-guides/use-cases/actions/implement-an-action

Final Checklists

最终检查清单

Action:
  • Nango root verified
  • references/actions.md
    was used for the action pattern
  • Schemas and types are clear, and missing-value rules match the provider versus normalized contract
  • createAction()
    includes endpoint, input, output, and scopes when required
  • Fields use passthrough casing or the API's majority casing
  • Provider call includes an API doc link comment and intentional retries
  • nango.ActionError
    is used for expected failures
  • Registered in
    index.ts
  • Dryrun succeeds with
    --validate -e dev --no-interactive --auto-confirm --input '{...}'
  • <action-name>.test.json
    was generated by
    nango dryrun ... --save
    after
    --validate
  • nango generate:tests
    ran and
    npm test
    passes
Sync:
  • Nango root verified
  • references/syncs.md
    was used for the sync pattern
  • Models map is defined, ids are stable strings, and normalized models prefer
    .optional()
    unless
    null
    matters
  • Incremental was chosen first, with a checkpoint schema unless full refresh is explicitly justified from docs or payloads
  • nango.getCheckpoint()
    is read at the start and
    nango.saveCheckpoint()
    runs after each page or batch
  • Checkpoint data changes the provider request or resume state (
    since
    ,
    updated_after
    ,
    cursor
    ,
    page_token
    ,
    offset
    ,
    page
    ,
    since_id
    , etc.)
  • Changed-only checkpoint syncs (
    modified_after
    ,
    updated_after
    , changed-records endpoint) do not use
    trackDeletesStart()
    /
    trackDeletesEnd()
  • If checkpoints were not used, the response explains exactly why no viable checkpoint strategy exists
  • Raw provider schemas model omitted versus
    null
    correctly, and fields use passthrough casing or the API's majority casing
  • nango.paginate()
    is used unless the API truly cannot fit Nango's paginator
  • Deletion strategy matches the sync type:
    batchDelete()
    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
  • Metadata handled if required
  • Registered in
    index.ts
  • Dryrun succeeds with
    --validate -e dev --no-interactive --auto-confirm
  • <sync-name>.test.json
    was generated by
    nango dryrun ... --save
    after
    --validate
  • nango generate:tests
    ran and
    npm test
    passes
Action:
  • 已验证Nango根目录
  • 已参考
    references/actions.md
    实现action模式
  • Schema和类型定义清晰,缺失值规则符合provider与标准化契约的要求
  • createAction()
    包含端点、输入、输出,以及所需的权限范围
  • 字段使用透传大小写或API的主流大小写规范
  • Provider调用包含API文档链接注释和显式设置的重试次数
  • 预期失败场景使用
    nango.ActionError
    处理
  • 已在
    index.ts
    中注册
  • nango dryrun ... --validate -e dev --no-interactive --auto-confirm --input '{...}'
    执行成功
  • <action-name>.test.json
    是验证通过后通过
    nango dryrun ... --save
    生成的
  • 已运行
    nango generate:tests
    npm test
    通过
Sync:
  • 已验证Nango根目录
  • 已参考
    references/syncs.md
    实现sync模式
  • 已定义模型映射,id是稳定的字符串,标准化模型优先使用
    .optional()
    除非
    null
    有明确含义
  • 优先选择增量同步,带有检查点schema,除非文档或payload明确证明只能使用全量刷新
  • 运行开始时调用
    nango.getCheckpoint()
    ,每处理完一页或一批数据后调用
    nango.saveCheckpoint()
  • 检查点数据会修改provider请求或恢复状态(
    since
    updated_after
    cursor
    page_token
    offset
    page
    since_id
    等)
  • 仅返回变更的检查点sync(
    modified_after
    updated_after
    、变更记录端点)未使用
    trackDeletesStart()
    /
    trackDeletesEnd()
  • 如果未使用检查点,已明确说明不存在可行检查点策略的原因
  • 原始provider schema正确区分字段省略和
    null
    ,字段使用透传大小写或API的主流大小写规范
  • 除非API确实无法适配Nango的分页器,否则使用
    nango.paginate()
  • 删除策略与sync类型匹配:增量同步仅当provider返回显式删除记录时使用
    batchDelete()
    ;否则全量刷新 fallback 在拉取/保存前调用
    trackDeletesStart()
    ,仅在全量拉取+保存成功后调用
    trackDeletesEnd()
  • 已按要求处理Metadata
  • 已在
    index.ts
    中注册
  • nango dryrun ... --validate -e dev --no-interactive --auto-confirm
    执行成功
  • <sync-name>.test.json
    是验证通过后通过
    nango dryrun ... --save
    生成的
  • 已运行
    nango generate:tests
    npm test
    通过