@acms-subir/client

中文文档
0.1.37发布于 2026/11/05MITTypeScriptES Module零依赖近 30 天下载 3105

为ACMS公共移动API打入,无依赖客户端.

中文使用文档
文档目录8 节
  1. 预订、错误和注销
  2. 事件请求
  3. 推动通知
  4. 实况录像
  5. 缓存和信头
  6. 发展
  7. 管理预订和"我的预订"
  8. 编辑应用程序(工作人员登录)

@acms-subir/客户端

ACMS 公共 API v1. 支持 Expo/ React 的无依赖性ESM TypeScript客户端 本地、浏览器和节点 18+ 使用全局 fetch, (中文(简体) ), URL, (中文(简体) ), Headers 财务报告和审定财务报表 AbortController供应 fetch 当环境需要适配器时.

npm install @acms-subir/client
import { createClient, isAcmsError } from '@acms-subir/client';

const client = createClient({ baseUrl: 'https://example.com', locale: 'es' });
const site = await client.site();
const home = await client.home();
const page = await client.page('about/team');
for await (const post of client.paginate.posts({ collection: 'blog', limit: 50 })) {
  console.log(post.title);
}
const english = client.withLocale('en');

baseUrl 接受一个站点来源或完整 /api/v1 URL,带有可选选项 主机前缀 。 返回所有方法 未包装 data· ; openapi() 返回时 原始文档。 每个方法都接受 locale 财务报告和审定财务报表 signal 选项对象. 语言只发送到支持翻译的路径. withLocale 份额 与原始客户端的缓存和运输配置. site() 财务报告和审定财务报表 pushTopics() 从核心0.3.32开始使用一种语言; 旧网站拒绝它,所以 客户端再问一次没有它,并获得主语言. book() 发送客户端的 locale 因此,预定的电子邮件(和链接) 使用应用软件的语言; 在核心 0.3.38 拒绝该字段之前, 因此,客户的书 再次没有它, 用同样的钥匙, 在网站的主 语言。 更新网站后, 才能使用更新客户端发送应用程序构建 .

方法选项/ 行为
site(), (中文(简体) ), theme(), (中文(简体) ), home()身份(包括 legal.privacy 编号 : legal.terms 要在应用程序中链接的 URL 、 符號、 已解析的主页
page(slug, opts)已解析的页面, 包括段落; 支持嵌入式 satters
content(opts)kind, (中文(简体) ), collection, (中文(简体) ), q, (中文(简体) ), page, (中文(简体) ), limit, (中文(简体) ), cursor
contentById(id, opts)可选 kind 拆分导入的ID
posts(opts)内容过滤到员额; collection, (中文(简体) ), tag, (中文(简体) ), q标记
post(slug, opts)扫描邮政摘要,然后用ID加载细节;通过 collection 对于模糊的子弹
pages(opts)页次 总结,带有页形;使用 page() 用于款次
search(text, opts)顶级匹配 posts, (中文(简体) ), pages 财务报告和审定财务报表 events附加时 more 每组; types, (中文(简体) ), collection, (中文(简体) ), limit (1–20,默认5). 空文本解决无请求
events(opts)发生情况 from, (中文(简体) ), to, (中文(简体) ), calendar, (中文(简体) ), tag, (中文(简体) ), excludeTag, (中文(简体) ), room, (中文(简体) ), q帕吉纳克 过滤器使用一个值或数组( 其中任何一个匹配)
event(slug, opts)不论日期如何,用一发一发子弹GET /events/{slug}; 在超过核心0.3.40的站点上, 请求窗口中的第一个匹配)
eventDetail(slug, { on? })事件及其下一场,或者说 on (单位:千美元)YYYY-MM-DD(中文(简体) )
calendars()公共日历
resources(opts), (中文(简体) ), resource(slug, opts)公共资源; 搜索搜索列表页面
availability(opts)需求 resource, (中文(简体) ), link; 可选 from, (中文(简体) ), days, (中文(简体) ), minutes
roomFree({ room, start, end })自由或繁忙的一间房间,网站让人们检查,时间繁忙,没有名字;从未缓存(核心0.3.45+)
rsvpStatus(slug, { start })一个事件日期的RSVP状态: open 或者说 reason (单位:千美元)disabled, (中文(简体) ), ended, (中文(简体) ), closed 过了赛事的最后期限, cancelled, (中文(简体) ), full, (中文(简体) ), closesAt (当RSVPs到日期关闭时,或 null: 打开直到结束),活 going编号 :left (持有的等待列表点数已取出), maxSeats 现在有一个RSVP, autoConfirm, (中文(简体) ), waitlist (单位:千美元)enabled:全日期按顺序排列; waiting 人为 seats 席位; maxSeats 以一行为单位) form (问 题 version,或 null) (中文(简体) ). start 事件发生的起始时间与 events() 返回( UTC ISO 字符串, 如 2026-10-05T14:00:00.000Z) (中文(简体) ). 从未缓存
book(opts)资源预订或RSVP输入(RsvpInput 用于RSVP; waitlist: true 加入完整日期的等待列表, 状态 waitlisted),可选 idempotencyKey; 发送客户端的 locale (或 opts.locale用于电子邮件
openapi()Raw OpenAPI 文档
registerDevice({ token, platform, locale?, topics?, channels? })注册或刷新博览会推算符(每次启动应用程序都要呼叫); { created, device }。 。 。 . channels: Android 频道 所创建的应用程序(例如. ['urgent'](中文(简体) )
updateDevice(token, { topics?, locale?, channels? })更改设备的主题、语言或频道
unregisterDevice(token)退出(专有);也解除工作人员测试电话的链接
pushTopics()以客户语言(内置和网站本身)命名的作为通知切换的题目, kind: 'site'(中文(简体) )
bibles(), (中文(简体) ), biblePassage(ref, { bible }), (中文(简体) ), bibleChapter(book, chapter, { bible })在帖子(Settings → Bible, core 0.3.84+)中为圣经链接所写的圣经诗句: 站点的圣经,一个段落(一个链接) ?ref=),一个有标题和相邻的章节; 404 在关闭时
linkStaffPhone(token, code)仅工作人员:将这个已注册设备与管理员测试手机的6位数代码相接,从而获得此人的测试通知; { linked, staff: { name } }。错误的、使用过的或过期的代码是 400,太多尝试了 429; 从未重复过
unlinkStaffPhone(token)脱钩(专有); { linked: false, staff: null }
links()链接页:简介、社交和可见块(link, (中文(简体) ), email, (中文(简体) ), phone, (中文(简体) ), contact, (中文(简体) ), heading, (中文(简体) ), text, (中文(简体) ), spacer, (中文(简体) ), live, (中文(简体) ), embed(中文(简体) )
live()现场视频:当前广播(snapshot 或者说 null, (中文(简体) ), serverNow 和拥有者 display 选择。 从未缓存; 404 时 site.features.live 错误
announcements({ kind?, pinned?, following?, scope?, page?, limit? }), (中文(简体) ), announcement(id), (中文(简体) ), paginate.announcements()以客户语言发布最新消息pinned: true:旗帜,紧急第一;404 site.features.announcements 错误
form(id), (中文(简体) ), submitForm(id, { answers, version?, idempotencyKey? })已公布的窗体问题; 发送答案( 复选框组为数组) 。 每次呼叫都会发出一个键; 重复重用它
requestOptions(), (中文(简体) ), submitRequest(input, { idempotencyKey? })没有说明的事件请求:表格提供的内容open, (中文(简体) ), types, (中文(简体) ), rooms, (中文(简体) ), replyTime, (中文(简体) ), notice, (中文(简体) ), phone, (中文(简体) ), timezone; 从未缓存),并请求新事件或更改({ id }. 404 同时 site.features.requests 是虚假的。 见下文事件要求
manageBooking(token), (中文(简体) ), cancelBooking(token)书商自己订的 manageToken,并取消它(或留下一个等待者,或释放一个被扣留的地方); can 说什么是允许的。 一个等待名单的RSVP有 booking.position 以物配主 booking.holdUntil
confirmBooking(token)检查一下报到者can.confirm: confirmed,或 pending 当RSVP需要批准时. 410次 一次 holdUntil 通过了。 核心资源0.3.40或以后
rescheduleAvailability(token, { from?, days?, minutes? }), (中文(简体) ), rescheduleBooking(token, { start, minutes? })移动它的开放时间(它自己的时间算作自由),然后移动
bookingIcs(token)预订为 iCalendar 文件( 字符串)
requestGuestCode(email), (中文(简体) ), guestSignIn({ email, code, deviceName? }), (中文(简体) ), guestBookings(guestToken, { when? }), (中文(简体) ), guestSignOut(guestToken)"我的预订"的来宾报名

服务器没有后断层,事件细节或资源细节端点. 这些 便利方法可提出多项请求. event() 只发现事件 在其窗口中出现; 未列出 需要日历 calendar它不会引起任意的历史事件. 如果弹出后弹出相撞而未提供收藏,则第一个列出的比赛获胜.

搜索需要 site.features.search (除非网站设置) acms({ search: { enabled: false } })) (中文(简体) ). 它使用网站的搜索索引和 排名:标题数最多,再取出节选,标记和正文. 每个字 必须匹配,而最后一个匹配为前缀(birth 发现"出生日". q 打开 content()编号 :posts() 返回时 分级摘要、页前帖子和通过页数,每页最多200个 有点. search() 用于合并结果显示屏:每一次命中都带有简单文字 snippet 与 highlights (单位:千美元){ start, end } 区域)改为粗体,事件加 他们的下一个 occurrence启用 more.posts 提供"见",然后 posts({ q, collection })。匹配使用主语文本,所以 已翻译标题已显示,但没有搜索.

增殖用途 page编号 :nextPage,而不是不透明的光标. cursor 是数字 别名用于 page; 明示 page 赢了. tag 过滤器 每个获取的页面 当地,这样一页就可以空出一个非无 nextPage。继续 通过这些页面. paginate.content/posts/pages/events/resources 产量 单个项目(活动产生事件)。 他们不重复改变 服务器结果或提供快照一致性; 在您的应用程序中复制ID.

预订、错误和注销

import type { RsvpInput } from '@acms-subir/client';

// Persist a UUID v4 with this booking intent before submitting; reuse it until
// the outcome is known. Use your platform's secure UUID/storage facilities.
const idempotencyKey = crypto.randomUUID();
try {
  const result = await client.book({
    resource: 'hall', link: 'meeting', start: '2026-10-05T14:00:00Z', minutes: 60,
    name: 'Example Guest', email: '[email protected]', idempotencyKey,
  });
  // Store result.manageToken securely; it grants booking-management access.
} catch (error) {
  if (isAcmsError(error)) {
    console.log(error.status, error.code, error.message, error.retryAfter);
    // error.idempotencyKey preserves even an automatically generated key.
  }
}

// RSVP to one date of an event (needs only the calendar: site.features.rsvp)
const { occurrences } = await client.events({ q: 'supper' });
const date = occurrences[0];
const status = await client.rsvpStatus(date.event.slug, { start: date.start });
if (status.open) {
  const rsvp: RsvpInput = {
    event: date.event.slug, start: date.start, seats: 2, name: 'Example Guest', email: '[email protected]',
    // field id → answer; checkbox groups send a list
    answers: { meal: 'Vegetarian', help: ['Setup', 'Music'] },
    // required when the event asks questions: a changed form answers 409, so read the status again
    ...(status.form ? { formVersion: status.form.version } : {}),
  };
  // an email that already has an RSVP for this date: AcmsError 409 with code 'duplicate' (its link is emailed again)
  const result = await client.book({ ...rsvp, idempotencyKey: crypto.randomUUID() });
  // pending when the organiser approves RSVPs; status.form?.confirmation is the thank-you text.
  // result.manageToken changes or cancels it later (manageBooking, cancelBooking), like the email's link:
  // keep it in secure storage only.
  console.log(result.booking.status);
} else if (status.reason === 'full' && status.waitlist.enabled) {
  // a place in line (status 'waitlisted', no seats); when a spot opens the site emails them and holds it
  // for 24 hours: then manageBooking shows status 'offered' and holdUntil, and confirmBooking(token) takes it
  const result = await client.book({
    event: date.event.slug, start: date.start, seats: 2, name: 'Example Guest', email: '[email protected]', waitlist: true,
    ...(status.form ? { formVersion: status.form.version } : {}), idempotencyKey: crypto.randomUUID(),
  });
  console.log(result.booking.status);
}

const controller = new AbortController();
const pending = client.home({ signal: controller.signal });
controller.abort();
await pending.catch(() => {});

安全重复的请求(GET、PUT、DELETE、设备注册和 带有Idepotency-Key的 POST:预订、表格回复和事件请求)再试网络 失败,5xx和429答复最多两次(总共三次尝试) 250/500ms 备份和至少服务器的 Retry-After 延迟( 秒或 HTTP) (日期)。 等待会超过时间 timeoutMs 将429直接丢出 retryAfter。一发写出(请求和签名、取消和 移动预订、确认被扣位置、客人签出)永远不会自动重复: 网络出错, 请在再次尝试前检查状态 。 总是重复预订 重复使用同一序列体和UUID. 默认每个 book() 调用创建 使用键 crypto.randomUUID,返回到 Math.random UUID v4 中 无. 用于恢复呼叫/应用程序重新启动、供应和坚持 安全UUUID。 永远不要仅仅因为反应超时而产生新的意图.

timeoutMs 默认为 三万,并覆盖整个请求,包括复试, 缓存访问和身体读取。 较长的费率限制延迟可能使 预算。 明确中止和超时不自动重审;不确定 预订必须用它现有的钥匙重新测试. AcmsError 曝光情况 status, (中文(简体) ), code, (中文(简体) ), message, (中文(简体) ), retryAfter (秒),可选验证 issues 财务报告和审定财务报表 idempotencyKey本地失败使用状态 0 和 network_error, (中文(简体) ), timeout, (中文(简体) ), aborted,或 invalid_response; 非 JSON HTTP 错误使用 http_error。 。 。 . 方便查询对每一项基本请求分别适用超时.

事件请求

一个站点可以接收人们的事件请求 无账户( a)acms({ requests: true })这样 site.features.requests (b) 工作人员在日历中回答请求。 有人问 新的东西,或者换成一个事件, 并给出一个名字,电子邮件和 可选择的电话。 在工作人员批准之前,日历上没有任何内容.

import type { RequestInput } from '@acms-subir/client';

const options = await client.requestOptions();
// { open, types: [{ id, label }], rooms: [{ slug, name, color }], replyTime: '3 days', notice, phone, timezone }
if (!options.open) {
  // say "We aren't taking requests here right now." and show options.phone; keep the screen itself reachable
}
const ask: RequestInput = {
  kind: 'new', type: options.types[0]?.id, title: 'Guitar workshop',
  // the site's wall clock (options.timezone), in the future; the end may be just HH:mm on the same day
  start: '2026-11-07T18:00', end: '20:00',
  repeat: 'weekly',                       // 'once' (default), 'weekly', or 'other' with repeatText
  rooms: ['fellowship-hall'],             // slugs from options.rooms, or roomsUnsure: true
  people: 12, message: 'We bring our own chairs.',
  name: 'Example Guest', email: '[email protected]', phone: '555 0100',
};
const { id } = await client.submitRequest(ask, { idempotencyKey: crypto.randomUUID() });

// a change to a public event: one date of it (YYYY-MM-DD, the site's day), or leave date out for every date
await client.submitRequest({ kind: 'change', event: 'fall-fair', date: '2026-11-08', message: 'Could it start at 10?', name: 'Example Guest', email: '[email protected]' });
  • 请检查access-date=中的日期值 (帮助) roomFree({ room, start, end }) (需要在该网站上预订; 时间需要一个区域,所以转换 时钟数 options.timezone) (中文(简体) ).
  • 每个请求保留一个“同上不便键”并重新用于重试:重试 同样的回答 { id },与其他细节相同的密钥是 409 changed。每通电话没有 idempotencyKey 做了一个新的.
  • 客户的 locale (或 input.locale进入身体, 所以电子邮件 关于请求 说应用程序的语言.
  • 拒绝是 AcmsError 谁 code 说为什么: closed (409起请求) ),一个字段(400: title, (中文(简体) ), type, (中文(简体) ), start, (中文(简体) ), end, (中文(简体) ), past, (中文(简体) ), far, (中文(简体) ), repeat, (中文(简体) ), room, (中文(简体) ), people, (中文(简体) ), event, (中文(简体) ), date, (中文(简体) ), what (变化的 电文), name, (中文(简体) ), email, (中文(简体) ), phone, (中文(简体) ), changed (409个)或 busy 编号 : full (429个 retryAfter10个请求,每个地址一分钟,加上 站点日封顶.

推动通知

当网站允许推时可用(acms({ mobile: { push: true } })(三); 否则,这些返回一个404 AcmsError。托肯斯来自 expo-notifications (单位:千美元)getExpoPushTokenAsync) (中文(简体) ). 网站存储的纪念品, 平台、语言和专题.

const { topics } = await client.pushTopics();          // [{ id: 'news', label: 'News', kind: 'general' }, …]
await client.registerDevice({ token, platform: 'ios', locale: 'es', topics: ['news', 'events'] });
await client.updateDevice(token, { topics: ['events'] });
await client.unregisterDevice(token);

在一次活动之后: event.follow.topic (单位:千美元)event:<id>当它不能是 随行)像其它任何设备的主题一样进入设备主题;站点放弃了它 一旦事件没有日期了。 活动列表 a 电话:

const topics = [...device.topics, event.follow.topic!];
await client.updateDevice(token, { topics });
const following = followedEvents(topics);                          // event ids
await client.announcements({ following });                          // + their messages and notices (kind 'message')
await client.announcements({ following, scope: 'following' });      // only those ("My classes")

追随者也可以在每次约会之前,在 event.follow.reminders (单位:千美元)[{ id: '1h' | 'evening', topic, at }], (中文(简体) ), at 页:1 晚上时间 HH:mm现场时间; [] 当历法没有规定的时候 topic (单位:千美元)event:<id>:remind:1h在活动的主题之外,一个 一次; event.follow.reminderStart 新的跟踪者开始于 (单位:千美元)'none' =没有提醒,直到他们选择。 网站只保留一个提醒 它的话题, 当日历停止提供它时, 放弃它.

import { reminderOf, withReminder } from '@acms-subir/client';
reminderOf(device.topics, event.id);                                             // '1h' | 'evening' | null
await client.updateDevice(token, { topics: withReminder(device.topics, event.id, 'evening') }); // "The evening before, at 7:00 PM"
await client.updateDevice(token, { topics: withReminder(device.topics, event.id, null) });      // no reminder

event.hosts 当其日历显示时, 列出其主机; event.hostsLabel 日历用请求的语言(“Maestro/a”,或 '' 当它没有设定的时候.

工作人员可以把自己的电话连接起来进行测试(“发送测试与我 在管理员中:管理员的测试手机面板显示一次性6位数 代码(10分,单用),应用程序随这款手机的代号发送. device.staff (从) registerDevice 财务报告和审定财务报表 updateDevice和链接 反应名称与谁有关(仅与谁有关),或 null。测试推 携带 data.test: true。 。 。 .

const { staff } = await client.linkStaffPhone(token, '123456');  // { name: 'Ana López' }; 400 for a wrong, used or expired code
await client.unlinkStaffPhone(token);                             // turning notifications off unlinks it too

实况录像

site.features.live 网站现场视频(整合 ) 现场视频 视频)没有关闭. live() 返回网站显示的相同快照 : status (单位:千美元)live, (中文(简体) ), upcoming 或者说 offline 为"注意我们的频道"倒下, title, (中文(简体) ), watchUrl,绝对值 thumbUrl (空地当无), startedAt, (中文(简体) ), expiresAt 和可选 channel 财务报告和审定财务报表 viewers。时间是 Unix 数以毫秒计 服务器 时钟: 保留 serverNow - Date.now() 作为 并停止一次将快照作为电流处理 expiresAt (非零时) 即使后来的请求失败了 也要按那个时钟来. display 携带 拥有者的选择(style数字 : poster, (中文(简体) ), split 或者说 row· ; bar, (中文(简体) ), header, (中文(简体) ), dock(中文(简体) ) 因此,一个应用程序可以跟踪网站。 大约每30秒播放一次,而应用程序是 在前方; @acms-subir/native是因为 useLive() 做这一切。 这个 "我们现场直播"的通知是推题 live。 。 。 .

const { snapshot, serverNow } = await client.live();
const offset = serverNow - Date.now();
const current = snapshot && (!snapshot.expiresAt || snapshot.expiresAt > Date.now() + offset) ? snapshot : null;
if (current?.status === 'live') console.log(`Live: ${current.title} → ${current.watchUrl}`);

缓存和信头

ETag 重新验证默认为内存的 URL 键缓存 。 每个读取联系人 服务器 If-None-Match; 一个 304 重用保存的数据。 这不是一个 离线后退 将返回的缓存对象视为不可改变 。 使用 cache: false 来禁用它。 可用性,活状态,RSVP状态,预订结果和出错永远不会被缓存. 无ETag或与 no-store 取消旧条目.

import type { ClientCache } from '@acms-subir/client';
const cache: ClientCache = {
  async get(url) { /* retrieve { etag, body } from app storage */ return null; },
  async set(url, entry) { /* persist entry; null means delete */ },
};
const persistent = createClient({ baseUrl: 'https://example.com/api/v1', cache });

适配器可以是同步的或同步的. 将持续缓存限制为 一个站点的公开API 并账户存储限制。 缓存适配器失败 向打电话者宣传。 自定义 headers 支持; 不嵌入特权 证书。 请求省略浏览器权限 。 有条件的标题得到管理 由客户端; 逐个拨号的密钥会覆盖已配置的头键.

发展

npm run build -w packages/client
npm run test -w packages/client
npm run check:types -w packages/client
npm run generate:types -w packages/client  # after reviewing core schema changes

合同测试使用 Core 虚拟导入实际核心 OpenAPI 生成器 模块测试根,将所有 GET/POST 路径与客户端方法注册进行对比, 和检查生成的请求/答复类型字节。 总部和备选方案 是运输业务,没有单独的数据返回方法。 无核心 代码,Zod,或节点内置的飞船 在这个包的运行时间.

管理预订和"我的预订"

// a booking the app made (result.manageToken from book()), or one from guestBookings()
const view = await client.manageBooking(manageToken);
if (view.can.reschedule) {
  const open = await client.rescheduleAvailability(manageToken, { days: 7 });
  await client.rescheduleBooking(manageToken, { start: open.days[0].slots[0].start });
}
if (view.can.cancel) await client.cancelBooking(manageToken);

// guest sign-in (check site.features.guestSignIn first)
await client.requestGuestCode('[email protected]');
const { accessToken } = await client.guestSignIn({ email: '[email protected]', code: '481203' });
const mine = await client.guestBookings(accessToken, { when: 'upcoming' });

预订和来宾信使以信封形式旅行(Booking-Token, (中文(简体) ), Authorization: Bearer),从不在URL中,他们的回复也从不被缓存. 将两者安全储存(expo-secure-store) (中文(简体) ). can.closed 表示 预订类型更改截断已过:显示“联系我们”而不是“联系我们” 按钮。 一个来宾标志在未使用90天后结束;401表示再次签入.

编辑应用程序(工作人员登录)

用于网站 acms({ mobile: { editor: { redirectUris } } })工作人员在 在系统浏览器(OAuth 2.0 + PKCE);应用程序从未看到密码.

import { createEditorAuth, createEditorSession, createEditorClient } from '@acms-subir/client';

const auth = createEditorAuth({ baseUrl: 'https://example.com', clientId: 'org.example.staff', redirectUri: 'org.example.staff://auth' });
const session = createEditorSession({ auth, storage /* get/set backed by expo-secure-store */, onSignedOut });
const api = createEditorClient({ baseUrl: 'https://example.com', session });

const { url, verifier, state } = await auth.start({ deviceName: 'Ana’s iPhone' });
// open `url` with expo-web-browser openAuthSessionAsync, then:
const { code } = auth.parseRedirect(returnedUrl, state);
await session.signIn(await auth.exchangeCode({ code, codeVerifier: verifier }));

const doc = await api.getDocument('post', id);
await api.saveDocument('post', id, { revision: doc.revision, fields: { title: 'New title' } });

在反应土著通行证 crypto: { randomBytes, sha256 } 从前催眠到 createEditorAuth (Web Crypto是默认). 刷新为单飞; 401在刷新后再试一次 然后 onAuthError 运行。 写作携带 页:1 revision 你上膛了(第409次有人抢救).

时间安排和设置 : schedule({ from, to, resource? }) (至多63天) 预订、被封锁的时间、事件和资料), createBooking() (关于某人的) 代表, rescheduleBooking(id, …), (中文(简体) ), listResources() 编号 : getResource() 编号 : createResource() 编号 : updateResource() 编号 : deleteResource(), (中文(简体) ), createBookingLink() 编号 : updateBookingLink() 编号 : deleteBookingLink(), (中文(简体) ), blockTime() 编号 : unblockTime(), (中文(简体) ), listCalendars() 编号 : createCalendar() 编号 : updateCalendar() 编号 : deleteCalendar(), (中文(简体) ), listForms() 编号 : listFormResponses(), (中文(简体) ), getLinksPage() 编号 : saveLinksPage()。 。 。 . updateBookingLink(resourceId, linkId, { order: 0 }) 先放一个预订类型 在它的房间,一个它的预订页面和应用程序领先。 设置写入需要 me().permissions.schedule.manage; 窗体响应和 HTML 链接块需要 (a) 管理人或所有人(403人除外).

版本与发布记录

@acms-subir/client 共发布 38 个版本,首次发布于 2026/10/01;过去 12 个月发布了 38 个版本。

版本发布日期距今
0.1.37latest2026/11/052 天前
0.1.362026/10/299 天前
0.1.352026/10/2612 天前
0.1.342026/10/2612 天前
0.1.332026/10/2612 天前
0.1.322026/10/2613 天前

关于 @acms-subir/client 的常见问题

@acms-subir/client 是什么?

为ACMS公共移动API打入,无依赖客户端.

如何安装 @acms-subir/client?

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

@acms-subir/client 支持 TypeScript 吗?

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

@acms-subir/client 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@acms-subir/client 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@acms-subir/client 可以商用吗?

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

@acms-subir/client 的下载量有多少?

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

@acms-subir/client 还在维护吗?

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