@faiber/faiber-profile

中文文档
2.7.0发布于 2026/11/05TypeScriptES Module近 30 天下载 3864

Profiles, atomic partial updates, dynamic properties, geographic records, relationships, media, search, trusted services, and profile logs.

原始使用文档
文档目录13 节
  1. Install
  2. Configure
  3. Complete capability
  4. Learner balances and education
  5. Authentication and authorization
  6. Inputs, queries, responses, and transport
  7. Media and command responses
  8. Errors and cancellation
  9. Current space-member names
  10. Dynamic profile filters
  11. Fitness coaching
  12. Configurable role summaries
  13. Profile short IDs and search

@faiber/faiber-profile

Profiles, atomic partial updates, dynamic properties, geographic records, relationships, media, search, trusted services, and profile logs.

Install

npm install @faiber/faiber-profile

Configure

import { FaiberClient, MemoryTokenProvider } from "@faiber/sdk-core";
import { ProfileApi } from "@faiber/faiber-profile";

const tokens = new MemoryTokenProvider();
const client = new FaiberClient("profile", {
  domains: { profile: process.env.FAIBER_PROFILE_URL! },
  tokenProvider: tokens,
  axios: { timeout: 15_000, withCredentials: true },
});
const api = new ProfileApi(client);

const updated = await api.updateProfile(userId, {
  first_name: { en: "Ava", fa: "آوا" },
  phone: "+989121234567",
  properties: { workout_plan: plan, membership },
});
console.log(updated.data.data.profile);

Complete capability

This package exposes 239 registered operations from the profiles service. Common workflows have concise methods on api; every registered backend route is also available as a named function on api.operations. Generated operation input, query, response, path, verb, and permission contracts are exported from operations.types.

AreaOperationsHTTP methods
ai-summary20GET, PATCH, POST, PUT
campaign4GET, POST
city8DELETE, GET, PATCH, POST, PUT
country8DELETE, GET, PATCH, POST, PUT
custom-type5DELETE, GET, PATCH, POST
education4GET, POST, PUT
fitness32GET, POST, PUT
integration2GET
lifecycle24DELETE, GET, POST, PUT
log-action3POST
logger2GET
option5GET, POST
profile59DELETE, GET, PATCH, POST, PUT
profile-property8DELETE, GET, PATCH, POST, PUT
profile-search3POST
province8DELETE, GET, PATCH, POST, PUT
referral7DELETE, GET, POST, PUT
relation10DELETE, GET, POST, PUT
router3GET
session4GET, PATCH, PUT
setting2GET, POST
survey2GET, POST
trusted-service12DELETE, GET, PATCH, POST, PUT

updateProfile sends one atomic PATCH /api/v1/profile/{uuid}. Omitted fields stay unchanged. In the pinned general patch handler, job: null clears the job; other nullable scalar fields deserialize explicit null as omission. Use educationInformation for explicit clearing of its education/referral/attendance fields. Balances, enrollment state, roles, IDs, and avatar objects are not mass-assignable. The patch model does accept status, employee_type, and freemium_session_limit under profile:update. Use uploadAvatar and IDP role operations for those concerns.

Learner balances and education

Profile reads, including byRole("student"), expose top-level account_balance and wallet_balance from the Office-synchronized snapshot. null means not yet known; it is not zero. Listing profiles does not load financial history.

const educations = (await api.listEducations()).data.data; // EducationOption[]: { id, name }
const dependencies = (await api.educationDependencies()).data.data;
await api.educationInformation(idpUserUuid, {
  education_id: educations[0].id,
  attendance_mode: dependencies.attendance_mode[0].id,
  level: "beginner",
  referral_source: dependencies.referral_source[0]?.id ?? null,
  referrer_uuid: referrerUserId,
  description: "Learner notes",
});
await api.customTypes.create({ name: "job", value_type: "select", options: ["بیکار"] });

educationInformation is supported and calls PUT /api/v1/profile/update/education-information/{uuid}. The path must be an IDP user UUID, not a Profile record ID. The entire update is validated before saving. Omission leaves a field unchanged; null clears it. Attendance accepts online or in_person. Level accepts a nonempty string of at most 64 Unicode characters, not a number or a fixed enum. Referral source is an active code from the dependencies response; referrer UUID must identify an existing other user. Description is limited to 10,000 characters. Education must be an active lookup ID.

GET /api/v1/education and /education/dependencies require profile:read; education creation and updates require profile:update. Administrators can populate the restored lookup with api.education.create({name}). The migration restores the table and nullable column but cannot recover rows deleted by the old migration; recover any historical catalog from a backup rather than inventing IDs.

Authentication and authorization

Use a TokenProvider to forward the signed-in user's Bearer token, or enable withCredentials for secure HttpOnly cookie sessions. Declared IDP permissions are included in each operation's JSDoc. Most CRUD routes consume identity headers supplied by a trusted IDP gateway; the permission annotations export metadata and do not enforce permissions inside the handler. Summary routes additionally validate Bearer/cookie credentials with IDP on each call. Internal fitness credit/gift operations require their separately configured service Bearer tokens. The SDK does not embed API keys, credentials, localhost URLs, sandbox hosts, or production hosts.

Inputs, queries, responses, and transport

All methods return the complete Axios response, including status, headers, and request IDs. Request bodies and query objects are named exported interfaces. Profile list pagination uses page and per_page; filters use names such as filter[role] and filter[status]. Summary pages also use their exported query types. Standard Axios request options, headers, timeouts, adapters, interceptors, and AbortSignal cancellation are supported as the final argument.

Generic REST resources are capability-guarded. Calling a legacy method that the service does not register throws UnsupportedOperationError before sending a request instead of producing a backend 405.

Media and command responses

api.operations.profileAvatarShowGetApiV1ProfileMediaUuidAvatar(ownerUuid, {key}), profileAvatarShowGetApiV1ProfileUuidAvatar, profileImageShowGet, and profileMediaShowGet return raw binary bytes (ArrayBuffer | Uint8Array), with the service content type and cache policy in Axios response headers. Their key query is required. Avatar and content image reads are public; private media requires IDP authentication. Invalid owner prefixes or traversal return 403; missing objects return 404.

Uploads accept a multipart file field containing JPEG, PNG or WebP up to 5 MiB. The caller must own the target user UUID or have profile:update. Successful uploads return {url, key}; unsupported types return 415, missing/empty files 422, oversize files 413, and unconfigured storage 503.

Property updates return updated_keys and array_item_changes (added/removed IDs and counts), rather than the complete profile. Address, parent-link, delete and restore commands generally acknowledge success with an empty object. Bulk parent lookups return stored link rows with both IDP user UUIDs; bulk addresses resolve IDP UUIDs to rows whose profile_id is a separate Profile UUID.

Errors and cancellation

try {
  await api.client.get("/health", undefined, { signal: AbortSignal.timeout(5_000) });
} catch (error) {
  // Axios errors retain response.status and the service error body.
}

Use @faiber/faiber-ts-sdk when one application needs multiple Faiber services with one configuration.

Current space-member names

After retrieving eligible member IDs from Task, call profile.resolvePeople({ user_ids }) with 1–200 UUIDs per batch. The response contains active sandbox profiles with English/Persian names and canonical user_id; email and phone are withheld. No match or duplicate names require clarification before assignment. Requires profile:lookup and the standard authenticated client; invalid batches return an Axios 400 response. Request options support cancellation and timeouts.

Personal information includes job, a nullable job title. Pass { job: "Software engineer" } to sdk.profile.personalInformation(userId, ...); pass { job: null } to clear it. Omitting job preserves the saved value. Profile detail and list responses also include job, and general profile patch operations accept it.

Dynamic profile filters

Profile listings expose birthday, created_at, and referrer_uuid. The referrer field holds the referring user's IDP UUID. To set it, call api.educationInformation(userId, { referrer_uuid: referrerUserId }). Pass null to clear the referrer.

Use api.operations.profileSearchSearchPost({ search: "Ava", include: ["properties"] }) for the combined search endpoint. Every hit includes core, including the three listing fields above. The include array selects the optional properties and services sections. Omit it to return both.

listProfiles and all role-list operation queries, including ProfileStudentIndexGetQuery, accept bracket filters, repeated date ranges and sort. Prefer filterProfiles for typed operators and JSON values:

const response = await api.filterProfiles({
  filters: [
    { path: 'role', op: 'in', value: ['student', 'customer'] },
    { path: 'core.account_balance', op: 'lt', value: 0 },
    { path: 'properties.owner', op: 'in', value: ['supporter-user-uuid'] },
    { path: 'services.office.sync-user.enrollments.freemium_sessions', op: 'gte', value: 1 },
  ],
  sort: [{ path: 'core.created_at', dir: 'desc' }],
  page: 1,
  per_page: 20,
});
const profiles = response.data.data.profiles;

This method requires profile:read and uses the normal authenticated Faiber client. It returns the full Axios response and accepts cancellation signals, headers and timeouts as the second argument. Invalid clauses, dates or unavailable configured fields reject with an Axios error carrying HTTP 400.

Use role (or core.role) to filter profile-role names: eq matches one role, in matches any supplied role, and neq excludes profiles with that role. The separate role input still accepts a single role; when combined with clauses, all constraints apply together. Role names are not limited to the student use case.

Use core.<column>, properties.<key>[.<nested-field>], or services.<service-key>.<event-name>.<nested-field> paths. Properties must be active, filterable and visible in lists; trusted services must be active and their events visible in lists. Nested payload arrays match candidate elements. Clauses are ANDed; use json_contains with an array/object structure for fields that must match the same nested record. Operators are eq, neq, gt, gte, lt, lte, in, contains, exists and json_contains. Missing data satisfies neq; array sorting uses the minimum JSON candidate.

await api.operations.profileStudentIndexGet({
  'filter[birthday][]': ['2000-01-01', '2010-12-31'],
  'filter[created_at][]': ['2026-01-01', '2026-10-07'],
  'filter[gender]': 'female',
  sort: '-core.created_at',
});

Ranges require two ordered endpoints; an empty string leaves a bound open. Date-only creation-time upper bounds include that entire day. sort accepts comma-separated paths, with - for descending. Application concepts such as double_debt, supporter owner and work_id require stored configured properties or their actual trusted-service paths; the SDK does not calculate them. These capabilities require a service version supporting dynamic list filters.

Fitness coaching

The operations.fitness* methods cover intake drafts, product offers, paid orders, coach assignments, plan revisions, catalogs, settings, notifications and trial redemption. Exported FitnessIntake, FitnessPlan, FitnessOrder, FitnessRevision and gift types describe the wire models.

const self = await api.operations.fitnessMeGet();
const saved = await api.operations.fitnessSaveSettingsPut({
  model_ref: modelRef, stt_model_ref: speechInputRef, tts_model_ref: speechOutputRef,
  expected_version: currentVersion,
});

The service authorizes gym membership, managers, assigned coaches and order ownership independently of profile editing. Admin provisioning/import requires fitness:admin. Settings and drafts use optimistic versions; stale changes return 409. Purchase requests require a stable idempotency_key, and plan assignment/proposals use base_revision_id. Trusted gift administration and chat-credit reserve/settle operations are server-only and require dedicated bearer credentials. A user token does not mint credits or grant internal gift access. Directory workspaceResolvePeople continues to resolve 1–200 explicit UUIDs with profile:lookup; its results do not grant collaborator eligibility.

Configurable role summaries

Role summary configuration and persisted results belong to Profile. The authenticated caller needs profile:ai_summary:read_own for their own results or profile:ai_summary:read_all for other subjects in the same deployment. Parent relationships do not grant access. Configuration (configure) and queue management (manage) are separate permissions.

const response = await api.summaries.latest({ role_id: canonicalRoleId }, { signal });
console.log(response.status, response.data.data.freshness, response.data.data.summary);

Read the canonical role catalog with api.summaries.roles(), then create/edit a structured draft, validate it, preview an eligible subject, publish it, and enable it with setStatus(id, { enabled: true }). Global generation must be enabled before previewing; the global kill switch also blocks explicit previews with HTTP 409. A role can remain disabled while previewing its draft. Preview results remain distinct from published results and never publish the configuration. GET requests only read stored data. Accepted refresh and preview requests return HTTP 202; poll run/job state separately. A failed refresh can leave an older result available and stale. Disabled configurations hide latest content while explicitly authorized history reads remain available. Decimal metric values may be strings to preserve financial precision. Standard Axios errors, response headers and cancellation options are retained. These operations are also available as api.operations.aiSummary… methods.

const controller = new AbortController();
const matches = await profile.searchProfiles({
  search: "GDCN7L", // email, name, phone, national code, or six-character short ID
  role: "student",
  page: 1,
  per_page: 20,
}, { signal: controller.signal });
for (const person of matches.data.data.profiles) {
  console.log(person.short_id, person.id, person.user_id);
}

Use your configured ProfileApi instance and an AbortController. This wrapper requires profile:read and returns the full Axios response; errors and cancellation are preserved. listProfiles({ "filter[search]": text }), role lists, and filterProfiles use the same live matching. The generated operations.profileSearchSearchPost({ search: text }) also matches short IDs and returns short_id on every hit, even when include excludes core fields; that operation requires profile:search. The minimal people directory accepts the same lookup under profile:lookup without returning national codes.

Codes derive from the profile row's id, not user_id, without a new database column. Matching ignores case and normalizes Persian/Arabic digits. Enter the full six-character code; collisions return all matching results within pagination. Select the intended profile using its other details, then use its user_id for profile read/update routes. shortIdFromUuid is exported for offline display. Deploy the service's short-ID migration before using these searches.

版本与发布记录

@faiber/faiber-profile 共发布 65 个版本,首次发布于 2026/07/18;过去 12 个月发布了 65 个版本。

版本发布日期距今
2.7.0latest2026/11/059 天前
2.6.02026/11/049 天前
2.5.02026/11/049 天前
2.4.02026/11/0310 天前
2.3.02026/11/0211 天前
2.2.02026/11/0212 天前

关于 @faiber/faiber-profile 的常见问题

@faiber/faiber-profile 是什么?

Profiles, atomic partial updates, dynamic properties, geographic records, relationships, media, search, trusted services, and profile logs.

如何安装 @faiber/faiber-profile?

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

@faiber/faiber-profile 支持 TypeScript 吗?

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

@faiber/faiber-profile 支持 ESM 还是 CommonJS?

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

@faiber/faiber-profile 可以商用吗?

@faiber/faiber-profile 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@faiber/faiber-profile 的下载量有多少?

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

@faiber/faiber-profile 还在维护吗?

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