npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@edgeone/makers-sdk

v0.1.0-beta.2

Published

[English](README.md) | [中文](README.zh-CN.md)

Readme

EdgeOne Makers TypeScript SDK

English | 中文

面向 EdgeOne Makers 项目、环境变量与制品部署的 Node.js 20+ 仅 ESM 客户端。不支持浏览器运行时。

npm 包名:@edgeone/makers-sdk · 版本 0.1.0 · 合同 0.1.36 · MIT License

安装

npm install @edgeone/makers-sdk
import { Makers } from "@edgeone/makers-sdk";

Makers

构造

const makers = new Makers({
  token: process.env.MAKERS_API_TOKEN,
  region: "china",
});

| 参数 | 类型 | 必填 | 默认值 | 说明 | |------|------|:----:|-------|------| | token | string | 是 | — | EdgeOne Makers API Token | | source | string | 否 | sdk | 默认 "sdk"。显式传入如 "cli" 会原样转发。 | | region | "china" \| "global" | 否 | 自动探测 | chinapages-api.cloud.tencent.com/v1globalpages-api.edgeone.ai/v1 | | baseUrl | string | 否 | — | 优先于 region;必须 HTTPS(localhost 可 HTTP) | | timeoutMs | number | 否 | 30000 | 单次请求超时,毫秒 | | retries | number | 否 | 3 | 查询类最大重试次数;写操作不重试 | | logger | Logger | 否 | — | 需实现 debuginfowarnerror |

自动探测先试 china 再试 global,结果按 Makers 实例缓存。

公开成员

| 成员 | 类型 | 说明 | |------|------|------| | makers.projects | Projects | 项目与环境变量操作 | | makers.deployments | Deployments | 部署操作 | | makers.region | Region \| undefined | 只读;配置值或已探测到的值 |


Projects

projects.create(options)

创建项目。返回 { projectId },不含完整模型——需要名称、域名等信息须再调 get

const { projectId } = await makers.projects.create({
  name: "docs-site",
  area: "overseas",
  initialEnvVars: [{ key: "API_URL", value: "https://example.com" }],
});

| 参数 | 类型 | 必填 | 说明 | |------|------|:----:|------| | name | string | 是 | 同一账号下唯一;重复抛 ConflictError | | area | "mainland" \| "overseas" \| "global" | 否 | 加速区域;不传则不发送 | | initialEnvVars | EnvVar[] | 否 | 建项目时同时设环境变量 |

projects.list(options?)

const page = await makers.projects.list({
  name: "docs",
  page: 0,
  pageSize: 20,
  order: { field: "createdOn", direction: "desc" },
});

| 参数 | 类型 | 默认值 | 说明 | |------|------|-------|------| | projectIds | string[] | — | 按 ID 过滤 | | name | string | — | 按名称过滤 | | status | string | — | 按状态过滤 | | provider | string | — | 按 Provider 过滤 | | page | number | 0 | 从 0 开始 | | pageSize | number | 20 | 1–100 | | order | { field, direction } | — | field: "createdOn""modifiedOn"direction: "asc""desc" |

返回 Page<Project>{ items, page, pageSize, total, hasNext }

projects.listAll(options?)

for await (const project of makers.projects.listAll()) {
  console.log(project.projectId, project.name);
}

list 同参数但无 page。返回 AsyncIterable<Project>

projects.get({ projectId })

查询单个项目的完整模型。这是唯一能拿到 presetDomain(Production 域名)的地方。

const project = await makers.projects.get({ projectId });
console.log(project.presetDomain);

projects.update(options)

更新项目设置。只传入要改的字段,不传不清空。

await makers.projects.update({
  projectId,
  name: "new-name",
  rootDir: ".",
  outputDir: "dist",
  buildCmd: "npm run build",
  installCmd: "npm install",
  framework: "other",
  nodejsVersion: "20",
});

| 参数 | 类型 | 说明 | |------|------|------| | projectId | string | 必填 | | name | string | 项目名称 | | rootDir | string | 根目录 | | outputDir | string | 输出目录 | | buildCmd | string | 构建命令 | | installCmd | string | 安装命令 | | framework | string | 框架标识 | | nodejsVersion | string | Node.js 版本 |

projects.delete({ projectId })

删除项目。不可恢复。


环境变量

方法位于 makers.projects。公开字段:keyvalue、可选 comment。改项目变量使用 setEnvsdeploy 不接受环境变量。

projects.listEnvs({ projectId })

返回 EnvVar[]。值自动加入脱敏名单。

projects.setEnvs({ projectId, envVars })

批量 upsert。内部先读后写,非原子操作。重复 key 在发请求前抛 ValidationError

await makers.projects.setEnvs({
  projectId,
  envVars: [
    { key: "API_URL", value: "https://example.com", comment: "origin" },
  ],
});

projects.deleteEnvs({ projectId, keys })

按 key 删除。重复 key 抛 ValidationError


Deployments

deployments.deploy(options)

部署制品。必须且只能传一种变体:

| 变体 | 类型 | 行为 | |------|------|------| | files | Record<string, string \| Uint8Array> | SDK 在内存中打 Zip | | directory | string(可选 excludePatterns: string[]) | SDK 打包目录 | | archive | string(Zip 路径) | 安全校验后直接上传 |

// 内联文件
await makers.deployments.deploy({
  projectId,
  artifact: { files: { "index.html": "<h1>ok</h1>" } },
  wait: true,
});

// 应用源码(项目根)
await makers.deployments.deploy({
  projectId,
  artifact: { directory: "." },
  wait: true,
});

// 静态构建输出
await makers.deployments.deploy({
  projectId,
  artifact: { directory: "./dist", excludePatterns: ["**/*.map"] },
});

// 预构建 CLI 产物
await makers.deployments.deploy({
  projectId,
  artifact: { directory: "./.edgeone" },
  wait: true,
});

// Zip 文件
await makers.deployments.deploy({
  projectId,
  artifact: { archive: "./site.zip" },
});

| 参数 | 类型 | 默认值 | 说明 | |------|------|-------|------| | projectId | string | — | 必填 | | artifact | Artifact | — | 必填;三种变体互斥 | | env | "Production" \| "Preview" | "Production" | Preview 要求已有 Production 部署 | | wait | boolean | false | 为 true 时轮询到终态 | | waitTimeoutMs | number | 900000 | 最长等待时间(毫秒,15 分钟) | | pollIntervalMs | number | 5000 | 轮询间隔(毫秒) | | onUploadProgress | 回调 | — | 上传完成后触发一次 | | onStatusChange | 回调 | — | 每次状态变更触发 |

返回 Deploymentwait: false 时只有 deploymentIdprojectIdenv 三个字段,那不是可打开的站点链接。wait: true 到达 Success 后,previewUrl 是可打开链接,且会过期

目录输入:传入一个目录。常见输入是应用源码(项目根)、静态构建输出(该目录根上必须有 index.html),或预构建的 Makers/SSR 产物(本地 CLI build 后传 ./.edgeone)。应用源码是 SDK 的常规路径:SDK 按默认忽略规则打包上传,不在本地编译,也不会自己执行 npm run buildedgeone makers build。Upload 项目上传后,Pages 后端可能会跑 edgeone makers build。SDK 不会跑框架适配器。默认忽略是固定名单,不读 .gitignore。调用者提供的 archive 原样上传。

目录安全:拒绝符号链接;自动忽略 .gitnode_modules、artifact 根下的 .edgeone 目录、.env、日志、临时文件和系统文件。非 .edgeone directory 还会忽略任一以 . 开头的路径段;.well-known 会保留。更深路径中的 .edgeone 会保留。传入名为 .edgeone 的目录时按 CLI 布局打包(<父目录名>/.edgeone/...,上一级有 edgeone.json 则一并打入),并保留嵌套 node_modules 与隐藏文件。其它 directory 仍在任意深度丢掉 node_modules。默认忽略是固定名单,不是读 .gitignoreexcludePatterns 追加 POSIX glob,不支持取反 (!)。

deployments.wait(options)

轮询至终态:SuccessFailedTimeoutCancelledInvalid。到达 Success 后,previewUrl 是可打开站点 URL(默认上传项目会签名),且会过期get / list / wait: false 不会签名。

const result = await makers.deployments.wait({
  projectId,
  deploymentId,
  timeoutMs: 15 * 60 * 1000,
  pollIntervalMs: 5_000,
  onStatusChange: (event) => console.log(event.deployment.status),
});

| 参数 | 类型 | 默认值 | 说明 | |------|------|-------|------| | projectId | string | — | 必填 | | deploymentId | string | — | 必填 | | timeoutMs | number | 900000 | 超时抛 DeploymentTimeoutError不会取消线上部署 | | pollIntervalMs | number | 5000 | | | onStatusChange | 回调 | — | |

deployments.list(options)

| 参数 | 类型 | 默认值 | 说明 | |------|------|-------|------| | projectId | string | — | 必填 | | status | string[] | — | 按状态过滤 | | timeRange | { start, end } | — | ISO 8601 | | repoBranch | string[] | — | 按分支过滤 | | page | number | 0 | | | pageSize | number | 20 | | | order | { field, direction } | — | |

deployments.listAll(options)

list 同参数但无 page。返回 AsyncIterable<Deployment>

deployments.get({ projectId, deploymentId })

查询单个部署。不存在时抛 NotFoundError

deployments.getLog({ projectId, deploymentId })

返回 { logUrl } —— 构建日志地址。


数据模型

Project

| 字段 | 类型 | 必有 | 说明 | |------|------|:----:|------| | projectId | string | 是 | | | name | string | 是 | 同一账号下唯一 | | status | string | 是 | | | area | ProjectArea | 否 | "mainland" / "overseas" / "global" | | presetDomain | string | 否 | Production 域名;刚建的项目可能还没分配 | | createdOn | string | 是 | ISO 8601 | | modifiedOn | string | 是 | ISO 8601 |

Deployment

| 字段 | 类型 | 必有 | 说明 | |------|------|:----:|------| | deploymentId | string | 是 | | | projectId | string | 是 | | | env | string | 是 | "Production""Preview" | | status | string | 否 | 终态:Success / Failed / Timeout / Cancelled / Invalid | | previewUrl | string | 否 | wait Success 后为可打开站点 URL(会过期)。get / wait: false 可能仍是后端原始 URL,不可直接打开。 | | code | string | 否 | | | createdOn | string | 否 | wait: false 时不返回 | | modifiedOn | string | 否 | wait: false 时不返回 |

EnvVar

| 字段 | 类型 | 必有 | |------|------|:----:| | key | string | 是 | | value | string | 是 | | comment | string | 否 |

回调

UploadProgressEvent{ uploadedBytes, totalBytes, completedFiles, totalFiles }

StatusChangeEvent{ deployment: Deployment, previousStatus: string | null }


错误处理

所有错误继承 MakersError,公开字段:codemessagerequestIdhttpStatuscause

| 异常类 | 触发条件 | |--------|---------| | AuthError | Code 105 或 HTTP 401 | | ValidationError | Code 含 "Invalid" 或 HTTP 400 | | NotFoundError | Code 含 "NotFound" 或 HTTP 404 | | ConflictError | Code 含 "Conflict" 或 HTTP 409 | | RateLimitError | Code 110 或 HTTP 429 | | UploadError | COS 上传失败 | | TimeoutError | 请求超时 | | DeploymentTimeoutError | 等待部署终态超时(继承 TimeoutError) |

import { MakersError, NotFoundError, DeploymentTimeoutError } from "@edgeone/makers-sdk";

try {
  await makers.projects.get({ projectId: "missing" });
} catch (error) {
  if (error instanceof NotFoundError) {
    console.error(error.code, error.requestId, error.httpStatus);
  }
}

重试策略

查询类请求遇到网络错误、HTTP 408/429/5xx 或外层 Code: 110 时最多重试 retries 次(默认 3)。退避策略为全抖动指数退避、上限 10 秒,优先读 Retry-After 头。创建、更新和 COS 凭证请求不重试。


开发

npm install
npm run build
npm test