@crystallize/js-api-client

中文文档
7.6.0发布于 2026/10/30MITTypeScriptESM + CJS构建来源已验证近 30 天下载 5526

与Crystallize API合作的助手和打字的公用事业.

中文使用文档
文档目录27 节
  1. 安装
  2. 快开始
  3. 快速摘要
  4. 备选办法和环境
  5. 可用的 API 呼叫器
  6. 认证概览
  7. 处理错误
  8. 分析请求
  9. 图形QL 构建器: json- to- graphql- query
  10. 高级助手
  11. 目录获取器
  12. 导航获取器
  13. 产品水利机
  14. 顺序获取器
  15. 订单管理器
  16. 客户和客户小组管理员
  17. 订阅合同管理器
  18. 墨盒管理器 (Shop API)
  19. 商店API订单
  20. 商店 API 客户和锁
  21. 签字核查
  22. 插件有效载荷解密
  23. 为公用事业定价
  24. 二进制文件管理器
  25. 大众呼叫客户端( 已过期)
  26. 建议使用 p- 限额的替代品
  27. 遗产使用

JS API 客户端

与Crystallize API合作的助手和打字的公用事业.

v5是一个主要的更新:更简单的客户端,通过@crystallize/schema输入输入,以及专注于共同任务的管理者(目录,导航,水合,订单,客户,订阅,和推车).

安装

pnpm add @crystallize/js-api-client
# or
npm install @crystallize/js-api-client
# or
yarn add @crystallize/js-api-client

快开始

import { createClient } from '@crystallize/js-api-client';

const api = createClient({
    tenantIdentifier: 'furniture',
    // For protected APIs, provide credentials
    // accessTokenId: '…',
    // accessTokenSecret: '…',
    // staticAuthToken: '…',
    // and more
});

// Call any GraphQL you already have (string query + variables)
const { catalogue } = await api.catalogueApi(
    `query Q($path: String!, $language: String!) {
    catalogue(path: $path, language: $language) { name path }
}`,
    { path: '/shop', language: 'en' },
);

// Don't forget to close when using HTTP/2 option (see below)
api.close();

快速摘要

  • 一个有电话的客户: catalogueApi, (中文(简体) ), discoveryApi, (中文(简体) ), pimApi, (中文(简体) ), nextPimApi, (中文(简体) ), meApi,和商店API的呼叫器 shopCartApi, (中文(简体) ), shopOrderApi, (中文(简体) ), shopCustomerApi, (中文(简体) ), shopLockApi, (中文(简体) ), shopSubscriptionContractApi, (中文(简体) ), shopBookingApi
  • 高级助手: createCatalogueFetcher, (中文(简体) ), createNavigationFetcher, (中文(简体) ), createProductHydrater, (中文(简体) ), createOrderFetcher, (中文(简体) ), createOrderManager, (中文(简体) ), createCustomerManager, (中文(简体) ), createCustomerGroupManager, (中文(简体) ), createSubscriptionContractManager, (中文(简体) ), createCartManager, (中文(简体) ), createShopOrderManager, (中文(简体) ), createShopCustomerManager, (中文(简体) ), createShopLock
  • 公用事业: createSignatureVerifier, (中文(简体) ), createPluginPayloadDecrypter, (中文(简体) ), createBinaryFileManager, (中文(简体) ), pricesForUsageOnTier,请求 profiling
  • 使用对象构建图形QL json-to-graphql-query (见下文一节)
  • 强打字通过 @crystallize/schema 投入和产出
  • 升级? 见 升级 v4 – v5 迁移

备选办法和环境

createClient(configuration, options?)

  • 配置
    • tenantIdentifier (必须)
    • tenantId 选项
    • accessTokenId 编号 : accessTokenSecret 或者说 sessionId
    • bearerToken 用于后端发行的 Bearer 令牌(同意为 Authorization: Bearer …(中文(简体) )
    • staticAuthToken 只读目录/发现
    • shopApiToken 选项; 否则自动比对
    • shopApiStaging 使用中转商店 API
    • origin 自定义主机后缀( 默认为 .crystallize.com(中文(简体) )
  • 选项
    • useHttp2 启用 HTTP/2 运输
    • timeout 请求超时以毫秒计; 需要更长时间的请求将被中止
    • http2IdleTimeout HTTP/2 以毫秒计的空闲超时( 默认) 300000 ——5分钟). 对没有服务器的函数使用更短的值, 对长期运行的服务器使用更长的值
    • profiling 调用
    • extraHeaders 所有呼叫的额外请求信头
    • shopApiToken 自动牵引控制 : { doNotFetch?: boolean; scopes?: string[]; expiresIn?: number }。 。 。 . scopes 默认为 ['cart'];通过您使用的每一端点(例如. ['cart', 'order'])在前面获得一个单一的指使,否则指使会与外延范围被重置,这是第一次叫另一个商店API终点

client.close() 当您允许 HTTP/2 优雅地结束基础会话时, 将会被调用 .

可用的 API 呼叫器

  • catalogueApi -目录图形QL
  • discoveryApi - 发现图QL(取代了旧的搜索 API)
  • pimApi - PIM GraphQL(经典/图克快传)
  • nextPimApi - PIM 下图QL(适用于租户)
  • meApi - 我图QL(/@me范围)
  • shopCartApi - 商店API /cart GraphQL( 为您处理的文件夹)
  • shopOrderApi, (中文(简体) ), shopCustomerApi, (中文(简体) ), shopLockApi, (中文(简体) ), shopSubscriptionContractApi, (中文(简体) ), shopBookingApi - 其他商店API终点(/order, (中文(简体) ), /customer, (中文(简体) ), /lock, (中文(简体) ), /subscription-contract, (中文(简体) ), /booking(中文(简体) )

所有的商店API的呼叫者 一个客户共享一个符号。 它在过期前5分钟被刷新,当呼叫者需要一个被缓存的代币不覆盖的端点时,它会与瞄准镜的结合进行回放.

所有呼叫者都拥有相同的签名: <T>(query: string, variables?: Record<string, unknown>) => Promise<T>。 。 。 .

认证概览

将有关全权证书交给 createClient数字 :

  • staticAuthToken 对目录/发现只读
  • accessTokenId + 键 accessTokenSecret (或 sessionId用于PIM/Shop操作
  • bearerToken 用于后端发行的令牌——作为 Authorization: Bearer …; 已接受 catalogueApi, (中文(简体) ), discoveryApi, (中文(简体) ), pimApi, (中文(简体) ), nextPimApi,以及 meApi在不提供其他证书的情况下,也自动用于获取商店 API 令牌.
  • shopApiToken 选项; 如果省略, 将使用您的 PIM 证书在第一个商店 API 呼叫中获取一个符号

认证优先级( 每名呼叫者, 最高第一) : sessionId → bearerToken → staticAuthToken → accessTokenId编号 :accessTokenSecret。 。 。 .

认证文件见官方文件: https://crystalize.com/learn/developer-guides/api-overview/ 认证

处理错误

API 调用错误 JSApiClientCallError 两者 code 财务报告和审定财务报表 statusCode hTTP 状态的属性 :

import { JSApiClientCallError } from '@crystallize/js-api-client';

try {
    await api.pimApi(`query { … }`);
} catch (e) {
    if (e instanceof JSApiClientCallError) {
        console.error(`HTTP ${e.statusCode}:`, e.message);
        // e.code also works (same value)
    }
}

分析请求

如果有日志查询,计时和服务器计时.

import { createClient } from '@crystallize/js-api-client';

const api = createClient(
    { tenantIdentifier: 'furniture' },
    {
        profiling: {
            onRequest: (q) => console.debug('[CRYSTALLIZE] >', q),
            onRequestResolved: ({ resolutionTimeMs, serverTimeMs }, q) =>
                console.debug('[CRYSTALLIZE] <', resolutionTimeMs, 'ms (server', serverTimeMs, 'ms)'),
        },
    },
);

图形QL 构建器: json- to- graphql- query

这个图书馆充满了赞美 json- to- graphql- query (英语) 在引擎盖下 你可以使用简单的JS对象来构建GraphQL查询. 多数帮助者接受一个对象并将其转换成图形QL字符串.

  • 仍可用生弦给低级呼叫者打电话.
  • 对于与目录有关的助手,我们揭露 catalogueFetcherGraphqlBuilder 以组成可重复使用的碎片.

示例对象 — 查询字符串 :

import { jsonToGraphQLQuery } from 'json-to-graphql-query';

const query = jsonToGraphQLQuery({
    query: {
        catalogue: {
            __args: { path: '/shop', language: 'en' },
            name: true,
            path: true,
        },
    },
});

高级助手

这些帮助者构建查询,使用 @crystallize/schema,并给你打电话正确的API.

目录获取器

import { createCatalogueFetcher, catalogueFetcherGraphqlBuilder as b } from '@crystallize/js-api-client';

const fetchCatalogue = createCatalogueFetcher(api);

const data = await fetchCatalogue<{ catalogue: { name: string; path: string } }>({
    catalogue: {
        __args: { path: '/shop', language: 'en' },
        name: true,
        path: true,
        ...b.onProduct({}, { onVariant: { sku: true, name: true } }),
    },
});

导航获取器

import { createNavigationFetcher } from '@crystallize/js-api-client';

const nav = createNavigationFetcher(api);
const tree = await nav.byFolders('/', 'en', 3, /* extra root-level query */ undefined, (level) => {
    if (level === 1) return { shape: { identifier: true } };
    return {};
});

产品水利机

通过路径或具有可选价格背景的SKU获取产品/变量数据.

import { createProductHydrater } from '@crystallize/js-api-client';

const hydrater = createProductHydrater(api, {
    marketIdentifiers: ['eu'],
    priceList: 'b2b',
    priceForEveryone: true,
});

const products = await hydrater.bySkus(
    ['SKU-1', 'SKU-2'],
    'en',
    /* extraQuery */ undefined,
    (sku) => ({ vatType: { name: true, percent: true } }),
    () => ({ priceVariants: { identifier: true, price: true } }),
);

顺序获取器

import { createOrderFetcher } from '@crystallize/js-api-client';

const orders = createOrderFetcher(api);
const order = await orders.byId('order-id', {
    onOrder: { payment: { provider: true } },
    onOrderItem: { subscription: { status: true } },
    onCustomer: { email: true },
});

const list = await orders.byCustomerIdentifier('customer-123', { first: 20 });

已键入实例( TypeScript 通用名) :

type OrderExtras = { payment: { provider: string }[] };
type OrderItemExtras = { subscription?: { status?: string } };
type CustomerExtras = { email?: string };

const typedOrder = await orders.byId<OrderExtras, OrderItemExtras, CustomerExtras>('order-id', {
    onOrder: { payment: { provider: true } },
    onOrderItem: { subscription: { status: true } },
    onCustomer: { email: true },
});

typedOrder.payment; // typed as array with provider
typedOrder.cart[0].subscription?.status; // typed
typedOrder.customer.email; // typed

订单管理器

创建/更新订单,设定付款或转入管道阶段. 输入以 @crystallize/schema。 。 。 .

import { createOrderManager } from '@crystallize/js-api-client';

const om = createOrderManager(api);

// Register (minimal example)
const confirmation = await om.register({
    cart: [{ sku: 'SKU-1', name: 'Product', quantity: 1, price: { gross: 100, net: 80, currency: 'USD' } }],
    customer: { identifier: 'customer-123' },
});

// Update payments only
await om.setPayments('order-id', [
    {
        provider: 'STRIPE',
        amount: { gross: 100, net: 80, currency: 'USD' },
        method: 'card',
    },
]);

// Put in pipeline stage
await om.putInPipelineStage({ id: 'order-id', pipelineId: 'pipeline', stageId: 'stage' });

客户和客户小组管理员

import { createCustomerManager, createCustomerGroupManager } from '@crystallize/js-api-client';

const customers = createCustomerManager(api);
await customers.create({ identifier: 'cust-1', email: '[email protected]' });
await customers.update({ identifier: 'cust-1', firstName: 'John' });

const groups = createCustomerGroupManager(api);
await groups.create({ identifier: 'vip', name: 'VIP' });

订阅合同管理器

创建/更新合同并生成一个变体预填模板.

import { createSubscriptionContractManager } from '@crystallize/js-api-client';

const scm = createSubscriptionContractManager(api);

const template = await scm.createTemplateBasedOnVariantIdentity(
    '/shop/my-product',
    'SKU-1',
    'plan-identifier',
    'period-id',
    'default',
    'en',
);

// …tweak template and create
const created = await scm.create({
    customerIdentifier: 'customer-123',
    tenantId: 'tenant-id',
    payment: {
        /* … */
    },
    ...template,
});

墨盒管理器 (Shop API)

托肯处理是自动的( 除非你通过) shopApiToken 设置 shopApiToken.doNotFetch: true) (中文(简体) ).

import { createCartManager } from '@crystallize/js-api-client';

const cart = createCartManager(api);

// Hydrate a cart from input
const hydrated = await cart.hydrate({
    language: 'en',
    items: [{ sku: 'SKU-1', quantity: 1 }],
});

// Add/remove items, abandon or place and fulfill the cart and assign the orderId
await cart.addSkuItem(hydrated.id, { sku: 'SKU-2', quantity: 2 });
await cart.setCustomer(hydrated.id, { identifier: 'customer-123', email: '[email protected]' });
await cart.setMeta(hydrated.id, { merge: true, meta: [{ key: 'source', value: 'web' }] });
await cart.abandon(hydrated.id);
await cart.place(hydrated.id);
await cart.fulfill(hydrated.id, orderId);

商店API订单

createShopOrderManager 与商店API谈话 /order 终点:将一推车转换成退货订单,记录付款情况,并通过管线移动订单。 (createOrderManager 以上针对核心API.) 输入用来自 @crystallize/schema/shop,每个方法返回顺序 id 加上您选择的字段.

import { createShopOrderManager } from '@crystallize/js-api-client';
import type { Order } from '@crystallize/schema/shop';

const orders = createShopOrderManager(api);

const order = await orders.createFromCart(cartId, {
    type: 'standard',
    paymentStatus: 'paid',
    payments: [{ provider: 'stripe', transactionId: 'pi_123', amount: 100, method: 'card' }],
    pipelines: [{ identifier: 'fulfilment', stage: 'new' }],
});

await orders.addPayments(order.id, [{ provider: 'gift-card', amount: 20, meta: [{ key: 'code', value: 'XMAS' }] }]);
await orders.setPayments(order.id, [{ provider: 'stripe', amount: 120 }]); // replaces all payments
await orders.setMeta(order.id, { meta: [{ key: 'source', value: 'web' }] }); // merge: true by default
await orders.setCustomer(order.id, { isGuest: false, identifier: 'customer-123', type: 'individual', addresses: [] });
await orders.addToStage(order.id, 'fulfilment', 'shipped');
await orders.removeFromPipeline(order.id, 'fulfilment');

const fetched = await orders.fetch<Order>(order.id, { reference: true, payments: { provider: true, meta: true } });
const history = await orders.listByCustomer('customer-123', { limit: 10, skip: 0 }, { reference: true });
  • payments 接受任何 provider 字符串:它们记录了所发生的事情,没有任何指控.
  • payments[].meta 以 [{ key, value }] 列表,但读回为 JSON 对象({ code: 'XMAS' }) (中文(简体) ).
  • createFromCart, (中文(简体) ), addPayments 财务报告和审定财务报表 setPayments 在回复后继续执行命令:在回复后立即发布的读数仍可返回先前状态.
  • fetch 以 JSApiClientCallError 当命令不存在时.

商店 API 客户和锁

import { createShopCustomerManager, createShopLock } from '@crystallize/js-api-client';

// `/customer`: customers keyed by identifier
const customers = createShopCustomerManager(api);
await customers.upsert({ identifier: 'customer-123', email: '[email protected]', firstName: 'John' }); // create or update
await customers.addAddress('customer-123', { type: 'delivery', street: 'Main St 1', city: 'Oslo' });
await customers.setAddress('customer-123', 0, { type: 'delivery', street: 'Main St 2', city: 'Oslo' });
await customers.removeAddress('customer-123', 0);
await customers.setMeta('customer-123', { meta: [{ key: 'tier', value: 'gold' }] });
const customer = await customers.fetch('customer-123', { email: true, addresses: { city: true } });

// `/lock`: a distributed lock, e.g. so a webhook and a redirect don't both create the order
const lock = createShopLock(api);
if (await lock.acquire(`cart-${cartId}`, 30)) {
    // ttl in seconds, defaults to 60; resolves false when the lock is already held
    try {
        // …createFromCart
    } finally {
        await lock.release(`cart-${cartId}`);
    }
}

签字核查

使用 createSignatureVerifier 以验证用于webhooks,apps或前端呼叫的 Crystalization 签名. 核查员将HS256 JWT信封与共享的密件解码,并与其匹配 hmac sHA-256索赔——全部通过捆绑的 jose 和平台的 crypto.subtle,所以你不需要通过自己的JWT或散去执行.

import { createSignatureVerifier } from '@crystallize/js-api-client';

const verify = createSignatureVerifier({ secret: process.env.CRYSTALLIZE_SIGNATURE_SECRET! });

// POST example
await verify(signatureJwtFromHeader, {
    url: request.url,
    method: 'POST',
    body: rawBodyString, // IMPORTANT: raw body
});

// GET webhook example (must pass the original webhook URL)
await verify(signatureJwtFromHeader, {
    url: request.url, // the received URL including query params
    method: 'GET',
    webhookUrl: 'https://example.com/api/webhook', // the configured webhook URL in Crystallize
});

插件有效载荷解密

使用 createPluginPayloadDecrypter 解密一个 Crystallize 插件 JWE 有效载荷(外部 JWE = 嵌入式 JWS 信封 = 逐地) encryptedSecrets),并可选择性地对照JWKS验证内置JWS. 这是CLI的单一切入点,任何供应商方的整合都应依赖此.

工厂取自销售商的私人JWK(如: crystallize plugin keygen)和可选 verify 设置,并返回可重复使用的函数,每个调用接受JWE紧凑的有效载荷。 私钥和JWKS解析器是一次建造并被再用——因此对于一个处理许多webhook呼叫的服务器,在启动时创建解密器一次.

仅 RSA-OAEP 编号 : RSA-OAEP-256 与 A*GCM 内容加密在外 JWE 上被接受. 当外头带着 cty: "JWT",简文作为紧凑的JWS处理,其索赔构成信封.

签名验证为选入:通过 verify 以使之得以实现。 何时 verify (a) 删去(或在核查失败时)信封和每个外地的秘密仍被退回,以便打电话者检查; signature.verified 编号 : signature.skipped 编号 : signature.reason 告诉你是否相信结果.

import { readFile } from 'node:fs/promises';
import { createPluginPayloadDecrypter } from '@crystallize/js-api-client';

const privateJwk = JSON.parse(await readFile('./private.jwk.json', 'utf8'));

// Decrypt only — no signature check. Good for local dev / smoke tests.
const decrypt = createPluginPayloadDecrypter({ privateJwk });
const decoded = await decrypt(jweCompact);

if (decoded.envelope) {
    console.log('tenant:', decoded.envelope.tenantIdentifier);
    console.log('config:', decoded.envelope.config);
    console.log('secrets:', decoded.secrets); // { StripeApiKey: 'sk_live_…', … }
}

以通过方式启用校验 verify 至少有一个 audience (您的插件标识符). issuer 默认为 https://api.crystallize.com 财务报告和审定财务报表 jwksUrl 默认为 ${issuer}/.well-known/jwks.json,所以生产用途是单行道:

// Production — issuer + JWKS URL default to api.crystallize.com.
const decrypt = createPluginPayloadDecrypter({
    privateJwk,
    verify: { audience: 'com.vendor.plugin' },
});

const verified = await decrypt(jweCompact);
if (!verified.signature.verified) {
    // Signature check skipped or failed — envelope + secrets are still populated but MUST be treated as untrusted.
    console.warn('signature not trusted:', verified.signature.reason);
}

其它 verify 字段 : clockTolerance (秒,默认为 30, (中文(简体) ), verifyBackendToken (还核查) envelope.backendToken 默认为 false) (中文(简体) ).

回来的 DecryptedPluginPayload 包含:

  • protectedHeader 外 JWE 保护头
  • innerProtectedHeader 内置JWS保护头,当有效载荷被嵌入时
  • envelope 核实(或解码)JWS索赔,或 null 用于未记录的有效载荷
  • plaintext 当有效载荷不是一窝JWT时,原始外平面文字,否则 null
  • secrets ——逐字解密的简单文字 envelope.encryptedSecrets
  • signature —— 说 { verified, skipped?, reason?, issuer?, audience?, algorithm? }
  • backendToken —— 说 { verified, skipped?, reason?, claims? } 何时 envelope.backendToken 在场,否则 null

警卫: secrets 并解码 envelope 索赔要求包含清晰的文字证明。 不日志或将其转入共享汇.

为公用事业定价

import { pricesForUsageOnTier } from '@crystallize/js-api-client';

const usage = 1200;
const total = pricesForUsageOnTier(
    usage,
    [
        { threshold: 0, price: 0, currency: 'USD' },
        { threshold: 1000, price: 0.02, currency: 'USD' },
    ],
    'graduated',
);

二进制文件管理器

通过预先签名的请求上传文件( 如图像) 。 仅限服务器侧.

import { createBinaryFileManager } from '@crystallize/js-api-client';

const files = createBinaryFileManager(api);
const mediaKey = await files.uploadImage('/absolute/path/to/picture.jpg');
const staticKey = await files.uploadFile('/absolute/path/to/static/file.pdf');
const bulkKey = await files.uploadMassOperationFile('/absolute/path/to/import.zip');
// Use the returned keys in subsequent PIM mutations

uploadImage 验证文件在创建前为图像 MEDIA 上传. 使用 uploadFile 适用于应居住在租户静态文件存储中的资产,以及 uploadMassOperationFile 由批量业务管道处理的进口货物。 打电话 uploadToTenant 需要下级控制(如自定义缓冲或上传类型)时直接.

大众呼叫客户端( 已过期)

折旧: 使用成熟的生态系统组合,如 p-limit 或者说 p-queue 换句话说 它们提供更好的错误处理,TypeScript支持,并被积极维护.

import pLimit from 'p-limit';
import { createClient } from '@crystallize/js-api-client';

const api = createClient({ tenantIdentifier: 'my-tenant', accessTokenId: '…', accessTokenSecret: '…' });
const limit = pLimit(5); // max 5 concurrent requests

const mutations = items.map((item) =>
    limit(() =>
        api.pimApi(
            `mutation UpdateItem($id: ID!, $name: String!) { product { update(id: $id, input: { name: $name }) { id } } }`,
            { id: item.id, name: item.name },
        ),
    ),
);

const results = await Promise.allSettled(mutations);
const failed = results.filter((r) => r.status === 'rejected');
console.log(`Done: ${results.length - failed.length} succeeded, ${failed.length} failed`);

遗产使用

大众呼叫客户端仍然在运行,但会在首次使用时发出去色警告.

有时,当你有很多电话需要处理, 无论是询问还是突变, 你都想能够同步管理它们。 这是大众呼叫客户端的目的. 它将使你成为同步,管理生命周期的起重,再试,增减速度等.

这些是主要特点:

  • 运行 首页 请求在批次中同步. 首页 默认的批量大小
  • 如果批次有超过50%的出错,则会保存出错并延续批次大小为 1
  • 如果批次中出现不到50%的出错,则会保存出错并延续当前批次大小倒数 1
  • 如果没有出错,它会逐批递增(+1)请求的数量,上限为 最大缩放
  • 如果错误率是100%,则根据 费博纳奇 递增
  • 所有批次结束后, 您可以重试失败的请求
  • 可选生命周期功能 打开批次 (同步)
  • 可选生命周期功能 失败 (同步) 允许您做一些事情, 并且决定让命令( 返回真实: 默认) 或立即返回虚假和重新执行, 或任何其他行动
  • 可选生命周期功能 在请求前 (同步)在每次请求前执行. 您可以返回更改的请求/承诺
  • 可选生命周期功能 请求后 (同步) 每次请求后执行 。 如果需要,你也会得到结果
const client = createMassCallClient(api, { initialSpawn: 1 });

async function run() {
    for (let i = 1; i <= 54; i++) {
        client.enqueue.catalogueApi(`query { catalogue { id, key${i}: name } }`);
    }

    const successes = await client.execute();
    console.log('First pass done ', successes);
    console.log('Failed Count: ' + client.failureCount());
    while (client.hasFailed()) {
        console.log('Retrying...');
        const newSuccesses = await client.retry();
        console.log('Retry pass done ', newSuccesses);
    }
    console.log('ALL DONE!');
}
run();

版本与发布记录

@crystallize/js-api-client 共发布 73 个版本,首次发布于 2022/03/26;过去 12 个月发布了 11 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
7.6.0latest2026/10/3012 天前
7.5.02026/10/071 个月前
7.4.02026/09/231 个月前
7.3.02026/07/293 个月前
7.2.12026/06/134 个月前
7.2.02026/05/076 个月前

关于 @crystallize/js-api-client 的常见问题

@crystallize/js-api-client 是什么?

与Crystallize API合作的助手和打字的公用事业.

如何安装 @crystallize/js-api-client?

在项目目录运行 npm install @crystallize/js-api-client,或使用 pnpm add / yarn add / bun add。

@crystallize/js-api-client 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@crystallize/js-api-client 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@crystallize/js-api-client 可以商用吗?

@crystallize/js-api-client 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@crystallize/js-api-client 的下载量有多少?

根据 npm 官方下载统计,@crystallize/js-api-client 在 2026/10/11 – 2026/11/09 这 30 天内被下载 5,526 次,日均约 184 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@crystallize/js-api-client 还在维护吗?

最新版本 7.6.0 发布于 2026/10/30(12 天前);至今共发布 73 个版本,其中过去 12 个月发布了 11 个;首次发布于 2022/03/26。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。