Token导航 LogoToken导航

Agent Skill · 前端设计

api-client-development(API client 开发)

用于辅助 API 设计、接口文档、请求响应结构和服务集成说明。它适合让 Agent 梳理 endpoint、生成 OpenAPI 草稿、检查字段命名、整理错误码或辅助前后端联调。使用时需要确认真实业务语义、鉴权方式、分页和错误处理规则;涉及生成接口文档时,应避免凭空补字段,最好从现有代码、schema 或接口样例中提取事实。

api-client-development 是前端设计类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为执行命令;许可证信息还不明确,第三方扫描已通过,按安装量在前端设计类的 10,216 个 Skill 里排第 7,444。

总安装 374周安装 15GitHub Stars 38下载 121核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:api-client-development(API client 开发)
来源仓库:https://github.com/salesforcecommercecloud/b2c-developer-tooling
仓库路径:skills/api-client-development
安装命令:
npx skills add https://github.com/salesforcecommercecloud/b2c-developer-tooling --skill api-client-development
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/salesforcecommercecloud/b2c-developer-tooling --skill api-client-development

这个 Skill 是做什么的

前端设计类 Skill 关注页面结构、视觉规范和组件写法,输出通常是可运行的界面代码。

基于 OpenAPI 规范生成类型安全的 API 客户端,支持 OAuth 作用域与中间件注入。适用于 Salesforce B2C 项目中的 SDK 开发,确保前后端契约一致性。使用时需放置 OpenAPI 文件至指定目录,并通过 openapi-fetch 生成客户端代码。

安装方式:通过 npx skills add 从 GitHub 仓库安装,兼容主流 AI 编程工具。注意:生成的类型应与业务实体对齐,避免过度泛化导致维护困难。

来源仓库内路径:skills/api-client-development

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/salesforcecommercecloud/b2c-developer-tooling…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要执行命令,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

api-client-development 怎么安装?

在终端执行 npx skills add https://github.com/salesforcecommercecloud/b2c-developer-tooling --skill ap…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

api-client-development 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

api-client-development 需要什么权限?

权限级别是执行命令。安装流程涉及命令执行,可能通过 npx skills add https://github.com/salesforcecommercecloud/b2c-developer-tooling --skill api-client-development 联网下载 Skill 或依赖。用户安装前应确认命令来源、仓库内容和执行环境。

api-client-development 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

api-client-development 用的人多吗?

公开数据是累计安装 374 次,近一周安装 15 次,下载 121 次,GitHub 38 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

api-client-development 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 需要执行命令,装到常用环境前要先评估影响面。
  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理前端设计类任务、又不想每次都手写提示词的人。

不太适合

  • 不能接受 Skill 在你机器上执行命令的人。
  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

前端设计类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
frontend-design

前端设计 · Codex、Claude

8,823,360126,072只读MIT通过
vercel-composition-patterns

Vercel 组合模式 · Codex、Claude

3,858,81625,893需要联网MIT通过
vercel-react-native-skills

Vercel React native skills 前端 · Codex、Claude

2,468,66425,878只读MIT通过
adapt

adapt 搜索 · Codex、Claude

2,027,04023,125操作浏览器未明确通过
bolder

bolder 分析 · Codex、Claude

2,004,28823,130只读未明确通过
api-client-development

API client 开发 · 本页

37438执行命令未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

API Client Development

This skill covers creating typed API clients using OpenAPI specifications, with proper authentication and OAuth scope handling. It builds on the patterns in SDK Module Development.

Overview

API clients in this project use:

  • openapi-fetch: Type-safe HTTP client generated from OpenAPI specs
  • openapi-typescript: Generates TypeScript types from OpenAPI specs
  • Middleware pattern: Auth and logging injected via openapi-fetch middleware

Creating a New API Client

1. Add the OpenAPI Spec

Place the spec in packages/b2c-tooling-sdk/specs/:

specs/
├── custom-apis-v1.yaml    # YAML or JSON
├── slas-admin-v1.yaml
└── ods-api-v1.json

2. Update Type Generation Script

In packages/b2c-tooling-sdk/package.json, add to the generate script:

{
  "scripts": {
    "generate:types": "openapi-typescript specs/data-api.json -o src/clients/ocapi.generated.ts && openapi-typescript specs/newapi-v1.yaml -o src/clients/newapi.generated.ts"
  }
}

Run generation:

pnpm --filter @salesforce/b2c-tooling-sdk run generate:types

3. Create the Client Module

// src/clients/newapi.ts
import createClient, {type Client} from 'openapi-fetch';
import type {AuthStrategy} from '../auth/types.js';
import type {paths, components} from './newapi.generated.js';
import {createAuthMiddleware, createLoggingMiddleware} from './middleware.js';

// Re-export generated types for consumers
export type {paths, components};

// Client type alias
export type NewApiClient = Client<paths>;

// Config interface
export interface NewApiClientConfig {
  hostname: string;
  // Add API-specific config here
}

// Factory function
export function createNewApiClient(
  config: NewApiClientConfig,
  auth: AuthStrategy
): NewApiClient {
  const client = createClient<paths>({
    baseUrl: `https://${config.hostname}/api/v1`,
  });

  // Middleware order: auth first (runs last), logging last (sees complete request)
  client.use(createAuthMiddleware(auth));
  client.use(createLoggingMiddleware('NEWAPI'));

  return client;
}

4. Export from Clients Barrel

// src/clients/index.ts
export {createNewApiClient, type NewApiClient, type NewApiClientConfig} from './newapi.js';
export type {paths as NewApiPaths, components as NewApiComponents} from './newapi.js';

SCAPI Client Pattern (OAuth Scope Injection)

SCAPI APIs require specific OAuth scopes. Instead of requiring CLI commands to manage scopes, encapsulate scope logic in the client factory.

The Problem

Without encapsulation, CLI commands leak auth implementation details:

// BAD: CLI command manages scopes
class MyCommand extends OAuthCommand {
  protected override loadConfiguration(): ResolvedConfig {
    const config = super.loadConfiguration();
    config.scopes = ['sfcc.custom-apis', `SALESFORCE_COMMERCE_API:${tenantId}`];
    return config;
  }
}

The Solution

Use OAuthStrategy.withAdditionalScopes() in the client factory:

// GOOD: Client encapsulates scope requirements
import {OAuthStrategy} from '../auth/oauth.js';
import type {AuthStrategy} from '../auth/types.js';

/** Default OAuth scopes required for this API */
export const MY_API_DEFAULT_SCOPES = ['sfcc.my-api'];

export interface MyApiClientConfig {
  shortCode: string;
  tenantId: string;           // Required for tenant-specific scope
  scopes?: string[];          // Optional override
}

export function createMyApiClient(
  config: MyApiClientConfig,
  auth: AuthStrategy
): MyApiClient {
  const client = createClient<paths>({
    baseUrl: `https://${config.shortCode}.api.commercecloud.salesforce.com/my-api/v1`,
  });

  // Build required scopes: domain scope + tenant-specific scope
  const requiredScopes = config.scopes ?? [
    ...MY_API_DEFAULT_SCOPES,
    buildTenantScope(config.tenantId),
  ];

  // If OAuth strategy, add required scopes; otherwise use as-is (e.g., for testing)
  const scopedAuth = auth instanceof OAuthStrategy
    ? auth.withAdditionalScopes(requiredScopes)
    : auth;

  client.use(createAuthMiddleware(scopedAuth));
  client.use(createLoggingMiddleware('MY-API'));

  return client;
}

This pattern:

  1. Keeps scope knowledge in the SDK, not the CLI
  2. Allows scope override for special cases via config.scopes
  3. Works with non-OAuth auth strategies (for testing/mocking)
  4. CLI commands just pass the auth strategy through unchanged

SCAPI Tenant ID Utilities

SCAPI APIs use an organizationId path parameter with the f_ecom_ prefix, but OAuth scopes use the raw tenant ID. Use these utilities:

// From @salesforce/b2c-tooling-sdk (or clients/custom-apis.ts)
import {toOrganizationId, normalizeTenantId, buildTenantScope} from '@salesforce/b2c-tooling-sdk';

// Convert tenant ID to organization ID (normalizes + adds f_ecom_ prefix)
toOrganizationId('zzxy_prd')        // Returns 'f_ecom_zzxy_prd'
toOrganizationId('f_ecom_zzxy_prd') // Returns 'f_ecom_zzxy_prd' (unchanged)
toOrganizationId('zzxy-prd')        // Returns 'f_ecom_zzxy_prd' (hyphen normalized)

// Normalize any tenant/org ID form to canonical underscore format
normalizeTenantId('f_ecom_zzxy_prd')                              // Returns 'zzxy_prd'
normalizeTenantId('zzxy-prd')                                     // Returns 'zzxy_prd'
normalizeTenantId('zzxy-prd.dx.commercecloud.salesforce.com')     // Returns 'zzxy_prd'

// Build tenant-specific OAuth scope (normalizes input)
buildTenantScope('zzxy_prd')        // Returns 'SALESFORCE_COMMERCE_API:zzxy_prd'
buildTenantScope('f_ecom_zzxy_prd') // Returns 'SALESFORCE_COMMERCE_API:zzxy_prd'
buildTenantScope('zzxy-prd')        // Returns 'SALESFORCE_COMMERCE_API:zzxy_prd'

Constants

/** Prefix required for SCAPI organizationId path parameter */
export const ORGANIZATION_ID_PREFIX = 'f_ecom_';

/** Prefix for tenant-specific SCAPI OAuth scopes */
export const SCAPI_TENANT_SCOPE_PREFIX = 'SALESFORCE_COMMERCE_API:';

OAuthStrategy.withAdditionalScopes()

The OAuthStrategy class has a method for scope injection:

// Creates a new OAuthStrategy with merged scopes
const scopedAuth = auth.withAdditionalScopes(['sfcc.custom-apis', 'SALESFORCE_COMMERCE_API:zzxy_prd']);

Key behaviors:

  • Returns a new OAuthStrategy instance (immutable pattern)
  • Merges scopes with deduplication (uses Set)
  • The new strategy shares token cache with the original (keyed by clientId)
  • If cached token doesn't have required scopes, it re-authenticates

Complete SCAPI Client Example

Reference implementation: packages/b2c-tooling-sdk/src/clients/custom-apis.ts

/*
 * Copyright (c) 2025, Salesforce, Inc.
 * SPDX-License-Identifier: Apache-2
 */
import createClient, {type Client} from 'openapi-fetch';
import type {AuthStrategy} from '../auth/types.js';
import {OAuthStrategy} from '../auth/oauth.js';
import type {paths, components} from './custom-apis.generated.js';
import {createAuthMiddleware, createLoggingMiddleware} from './middleware.js';

export type {paths, components};
export type CustomApisClient = Client<paths>;

/** Default OAuth scopes required for Custom APIs */
export const CUSTOM_APIS_DEFAULT_SCOPES = ['sfcc.custom-apis'];

export interface CustomApisClientConfig {
  shortCode: string;
  tenantId: string;
  scopes?: string[];
}

export function createCustomApisClient(
  config: CustomApisClientConfig,
  auth: AuthStrategy
): CustomApisClient {
  const client = createClient<paths>({
    baseUrl: `https://${config.shortCode}.api.commercecloud.salesforce.com/dx/custom-apis/v1`,
  });

  // Build required scopes: domain scope + tenant-specific scope
  const requiredScopes = config.scopes ?? [
    ...CUSTOM_APIS_DEFAULT_SCOPES,
    buildTenantScope(config.tenantId),
  ];

  // If OAuth strategy, add required scopes; otherwise use as-is
  const scopedAuth = auth instanceof OAuthStrategy
    ? auth.withAdditionalScopes(requiredScopes)
    : auth;

  client.use(createAuthMiddleware(scopedAuth));
  client.use(createLoggingMiddleware('CUSTOM-APIS'));

  return client;
}

// Tenant ID utilities
export const ORGANIZATION_ID_PREFIX = 'f_ecom_';
export const SCAPI_TENANT_SCOPE_PREFIX = 'SALESFORCE_COMMERCE_API:';

export function normalizeTenantId(value: string): string {
  let id = value.trim();
  if (id.includes('.')) id = id.split('.')[0];
  if (id.startsWith(ORGANIZATION_ID_PREFIX)) id = id.slice(ORGANIZATION_ID_PREFIX.length);
  return id.replaceAll('-', '_');
}

export function toOrganizationId(tenantId: string): string {
  return `${ORGANIZATION_ID_PREFIX}${normalizeTenantId(tenantId)}`;
}

export function buildTenantScope(tenantId: string): string {
  return `${SCAPI_TENANT_SCOPE_PREFIX}${normalizeTenantId(tenantId)}`;
}

CLI Command Integration

With scope encapsulation in the client, CLI commands become simple:

// packages/b2c-cli/src/commands/scapi/custom/status.ts
import {OAuthCommand} from '@salesforce/b2c-tooling-sdk/cli';
import {createCustomApisClient, toOrganizationId} from '@salesforce/b2c-tooling-sdk';

export default class ScapiCustomStatus extends OAuthCommand<typeof ScapiCustomStatus> {
  static flags = {
    ...OAuthCommand.baseFlags,
    'tenant-id': Flags.string({
      description: 'Organization/tenant ID',
      env: 'SFCC_TENANT_ID',
      required: true,
    }),
  };

  async run() {
    this.requireOAuthCredentials();

    const {'tenant-id': tenantId} = this.flags;
    const {shortCode} = this.resolvedConfig;

    // Auth strategy from base class - no scope configuration needed!
    const oauthStrategy = this.getOAuthStrategy();

    // Client handles scope injection internally
    const client = createCustomApisClient({shortCode, tenantId}, oauthStrategy);

    const {data, error} = await client.GET('/organizations/{organizationId}/endpoints', {
      params: {
        path: {organizationId: toOrganizationId(tenantId)},
      },
    });

    // Handle response...
  }
}

Testing API Clients

Use MSW (Mock Service Worker) to mock API responses:

import {http, HttpResponse} from 'msw';
import {setupServer} from 'msw/node';
import {createCustomApisClient} from '@salesforce/b2c-tooling-sdk';

const mockAuth: AuthStrategy = {
  async fetch(url, init) {
    return fetch(url, init);
  },
  async getAuthorizationHeader() {
    return 'Bearer mock-token';
  },
};

const server = setupServer(
  http.get('https://test.api.commercecloud.salesforce.com/dx/custom-apis/v1/organizations/*/endpoints', () => {
    return HttpResponse.json({
      data: [{apiName: 'test', status: 'active'}],
      total: 1,
      limit: 10,
    });
  })
);

beforeAll(() => server.listen());
afterAll(() => server.close());

it('fetches endpoints', async () => {
  const client = createCustomApisClient(
    {shortCode: 'test', tenantId: 'zzxy_prd'},
    mockAuth
  );

  const {data} = await client.GET('/organizations/{organizationId}/endpoints', {
    params: {path: {organizationId: 'f_ecom_zzxy_prd'}},
  });

  expect(data?.data).toHaveLength(1);
});

Error Handling

When API requests fail, use getApiErrorMessage() to extract clean, user-friendly error messages. This utility handles multiple error formats and ensures HTML response bodies (like error pages from stopped sandboxes) are never shown to users.

Using getApiErrorMessage

import {getApiErrorMessage} from '@salesforce/b2c-tooling-sdk/clients';

const {data, error, response} = await client.GET('/sites', {...});

if (error) {
  // Returns structured error message or "HTTP 521 Web Server Is Down"
  const message = getApiErrorMessage(error, response);
  this.error(`Failed to fetch sites: ${message}`);
}

Supported Error Patterns

The utility extracts messages from these patterns in priority order:

APIError StructureMessage Location
ODS/SLAS{error: {message}}error.error.message
OCAPI{fault: {message}}error.fault.message
SCAPI/Problem+JSON{title, detail}error.detail or error.title
Standard Error{message}error.message
FallbackAnyHTTP {status} {statusText}

Why This Matters

Without getApiErrorMessage:

ERROR: Failed to fetch sites: <!DOCTYPE html><html lang="en"><head><title>521 - Sandbox Down</title>...

With getApiErrorMessage:

ERROR: Failed to fetch sites: HTTP 521 Web Server Is Down

Important: Always Destructure response

When making API calls, always destructure the response object alongside error:

// GOOD: Include response for error handling
const {data, error, response} = await client.GET('/endpoint', {...});

// BAD: Missing response - can't get clean error message
const {data, error} = await client.GET('/endpoint', {...});

Troubleshooting

OAuth scope errors (401/403 from SCAPI): Ensure the client factory calls auth.withAdditionalScopes() with both the domain scope (e.g., sfcc.custom-apis) and the tenant-specific scope (SALESFORCE_COMMERCE_API:<tenantId>). Use buildTenantScope() which normalizes any tenant ID form (hyphenated, hostname, org ID) to canonical underscores before building scopes.

Type generation failures: Check that the OpenAPI spec in specs/ is valid YAML/JSON. Run pnpm --filter @salesforce/b2c-tooling-sdk run generate:types and inspect the output. Common issues: spec references external files that aren't present, or uses OpenAPI features not supported by openapi-typescript.

Middleware ordering issues: Auth middleware should be added first (client.use(createAuthMiddleware(...))), then logging. In openapi-fetch, middleware runs in reverse registration order for requests, so auth registered first means it runs last — ensuring the logging middleware sees the final request with auth headers.

organizationId mismatch: SCAPI path parameters need the f_ecom_ prefix (use toOrganizationId()), while OAuth scopes need the raw tenant ID (use normalizeTenantId()). Both functions accept any parseable form (hyphenated, hostname, org ID). Mixing these up causes 404s or scope errors.

Checklist: New SCAPI Client

  1. Add OpenAPI spec to specs/
  2. Update generate:types script in package.json
  3. Run pnpm --filter @salesforce/b2c-tooling-sdk run generate:types
  4. Create client module with:

- Config interface including tenantId - Default scopes constant - Factory function with scope injection pattern - Tenant ID utilities (or import from existing)

  1. Export from src/clients/index.ts
  2. Add to main src/index.ts if needed
  3. Write tests with MSW mocks
  4. Build: pnpm --filter @salesforce/b2c-tooling-sdk run build
  5. Test: pnpm --filter @salesforce/b2c-tooling-sdk run test

平台分布

Codex

37.3%
按下载量换算45

Claude

32.55%
按下载量换算39

Cursor

17.79%
按下载量换算22

Gemini CLI

9.89%
按下载量换算12

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

执行命令

安装流程涉及命令执行,可能通过 npx skills add https://github.com/salesforcecommercecloud/b2c-developer-tooling --skill api-client-development 联网下载 Skill 或依赖。用户安装前应确认命令来源、仓库内容和执行环境。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills