@h-ai/iam 0.1.0-alpha.49 → 0.1.0-alpha.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -439,8 +439,9 @@ const result = await iam.apiKey.createApiKey(userId, {
439
439
  })
440
440
  // result.data.rawKey → 明文密钥(仅此一次展示)
441
441
 
442
- // 列出用户的 API Key
443
- const keys = await iam.apiKey.listApiKeys(userId)
442
+ // 列出用户的 API Key(服务端分页)
443
+ const keys = await iam.apiKey.listApiKeys(userId, { page: 1, pageSize: 20, search: 'ci' })
444
+ // keys.data → { items, total, page, pageSize }
444
445
 
445
446
  // 吊销
446
447
  await iam.apiKey.revokeApiKey(keyId)
package/dist/index.d.ts CHANGED
@@ -286,6 +286,23 @@ interface CreateApiKeyOptions {
286
286
  /** 权限范围 */
287
287
  scopes?: string[];
288
288
  }
289
+ /** API Key 列表允许的服务端排序字段。 */
290
+ type ApiKeySortField = 'name' | 'createdAt' | 'lastUsedAt' | 'expiresAt';
291
+ /** API Key 列表排序方向。 */
292
+ type ApiKeySortDirection = 'asc' | 'desc';
293
+ /**
294
+ * API Key 列表查询选项
295
+ */
296
+ interface ListApiKeysOptions extends PaginationOptionsInput {
297
+ /** 搜索关键字(模糊匹配名称与密钥前缀) */
298
+ search?: string;
299
+ /** 按启用状态过滤,不传则返回全部 */
300
+ enabled?: boolean;
301
+ /** 服务端排序字段;未指定时保持按创建时间倒序的历史行为。 */
302
+ sortBy?: ApiKeySortField;
303
+ /** 服务端排序方向;仅在指定 sortBy 时生效,默认 desc。 */
304
+ sortDirection?: ApiKeySortDirection;
305
+ }
289
306
  /**
290
307
  * API Key 管理操作接口
291
308
  */
@@ -299,12 +316,13 @@ interface ApiKeyOperations {
299
316
  */
300
317
  createApiKey: (userId: string, options: CreateApiKeyOptions) => Promise<HaiResult<CreateApiKeyResult>>;
301
318
  /**
302
- * 列出用户的所有 API Key
319
+ * 分页列出用户的 API Key
303
320
  *
304
321
  * @param userId - 用户 ID
305
- * @returns API Key 列表(不含密钥哈希)
322
+ * @param options - 分页、搜索、过滤与排序选项
323
+ * @returns 分页 API Key 列表(不含密钥哈希)
306
324
  */
307
- listApiKeys: (userId: string) => Promise<HaiResult<ApiKey[]>>;
325
+ listApiKeys: (userId: string, options?: ListApiKeysOptions) => Promise<HaiResult<PaginatedResult<ApiKey>>>;
308
326
  /**
309
327
  * 获取 API Key 详情
310
328
  *
@@ -1497,4 +1515,4 @@ interface IamFunctions {
1497
1515
 
1498
1516
  declare const iam: IamFunctions;
1499
1517
 
1500
- export { type AgreementConfig, AgreementConfigSchema, type AgreementDisplay, type ApiKey, type ApiKeyConfig, ApiKeyConfigSchema, type ApiKeyCredentials, type ApiKeyOperations, type AuthResult, type AuthStrategy, type AuthStrategyType, AuthStrategyTypeSchema, type AuthnOperations, type AuthzOperations, type ConsumeTicketOptions, type ConsumedTicket, type CreateApiKeyOptions, type CreateApiKeyResult, type CreateSessionOptions, type Credentials, HaiIamError, type IamConfig, type IamConfigInput, IamConfigSchema, type IamConfigSettingsInput, type IamFunctions, type IssueTicketOptions, type IssuedTicket, type LdapClientFactory, type LdapConfig, LdapConfigSchema, type LdapCredentials, type ListUsersOptions, type LoginConfig, LoginConfigSchema, type OtpConfig, OtpConfigSchema, type OtpCredentials, type PasswordConfig, PasswordConfigSchema, type PasswordCredentials, type PasswordResetConfig, PasswordResetConfigSchema, type Permission, type PermissionQueryOptions, type PermissionType, type RbacConfig, RbacConfigSchema, type RegisterConfig, RegisterConfigSchema, type RegisterOptions, type RegisterResult, type Role, type SecurityConfig, SecurityConfigSchema, type Session, type SessionConfig, SessionConfigSchema, type SessionData, type SessionFieldUpdates, type SessionOperations, type StoredUser, type TicketGrant, type TicketOperations, type TokenPair, type UpdateCurrentUserInput, type User, type UserOperations, type UserSortDirection, type UserSortField, iam };
1518
+ export { type AgreementConfig, AgreementConfigSchema, type AgreementDisplay, type ApiKey, type ApiKeyConfig, ApiKeyConfigSchema, type ApiKeyCredentials, type ApiKeyOperations, type ApiKeySortDirection, type ApiKeySortField, type AuthResult, type AuthStrategy, type AuthStrategyType, AuthStrategyTypeSchema, type AuthnOperations, type AuthzOperations, type ConsumeTicketOptions, type ConsumedTicket, type CreateApiKeyOptions, type CreateApiKeyResult, type CreateSessionOptions, type Credentials, HaiIamError, type IamConfig, type IamConfigInput, IamConfigSchema, type IamConfigSettingsInput, type IamFunctions, type IssueTicketOptions, type IssuedTicket, type LdapClientFactory, type LdapConfig, LdapConfigSchema, type LdapCredentials, type ListApiKeysOptions, type ListUsersOptions, type LoginConfig, LoginConfigSchema, type OtpConfig, OtpConfigSchema, type OtpCredentials, type PasswordConfig, PasswordConfigSchema, type PasswordCredentials, type PasswordResetConfig, PasswordResetConfigSchema, type Permission, type PermissionQueryOptions, type PermissionType, type RbacConfig, RbacConfigSchema, type RegisterConfig, RegisterConfigSchema, type RegisterOptions, type RegisterResult, type Role, type SecurityConfig, SecurityConfigSchema, type Session, type SessionConfig, SessionConfigSchema, type SessionData, type SessionFieldUpdates, type SessionOperations, type StoredUser, type TicketGrant, type TicketOperations, type TokenPair, type UpdateCurrentUserInput, type User, type UserOperations, type UserSortDirection, type UserSortField, iam };
package/dist/index.js CHANGED
@@ -589,6 +589,12 @@ var HaiIamError = core.error.buildHaiErrorsDef("iam", IamErrorInfo);
589
589
 
590
590
  // src/authn/apikey/iam-authn-apikey-repository.ts
591
591
  var TABLE_NAME = "hai_iam_api_keys";
592
+ var API_KEY_SORT_COLUMNS = {
593
+ name: "name",
594
+ createdAt: "created_at",
595
+ lastUsedAt: "last_used_at",
596
+ expiresAt: "expires_at"
597
+ };
592
598
  var API_KEY_FIELDS = [
593
599
  {
594
600
  fieldName: "id",
@@ -718,12 +724,31 @@ var DbApiKeyRepository = class extends BaseReldbCrudRepository {
718
724
  }
719
725
  return ok(result.data);
720
726
  }
721
- async findByUserId(userId, tx) {
722
- const result = await this.findAll({ where: "user_id = ?", params: [userId] }, tx);
727
+ async findPageByUserId(userId, options, tx) {
728
+ const conditions = ["user_id = ?"];
729
+ const params = [userId];
730
+ if (options.search) {
731
+ const escaped = options.search.replace(/[%_\\]/g, "\\$&");
732
+ const keyword = `%${escaped}%`;
733
+ conditions.push("(name LIKE ? ESCAPE '\\' OR key_prefix LIKE ? ESCAPE '\\')");
734
+ params.push(keyword, keyword);
735
+ }
736
+ if (options.enabled !== void 0) {
737
+ conditions.push("enabled = ?");
738
+ params.push(options.enabled ? 1 : 0);
739
+ }
740
+ const sortColumn = options.sortBy ? API_KEY_SORT_COLUMNS[options.sortBy] : API_KEY_SORT_COLUMNS.createdAt;
741
+ const sortDirection = options.sortBy && options.sortDirection === "asc" ? "ASC" : "DESC";
742
+ const result = await this.findPage({
743
+ where: conditions.join(" AND "),
744
+ params,
745
+ orderBy: `${sortColumn} ${sortDirection}`,
746
+ pagination: { page: options.page, pageSize: options.pageSize }
747
+ }, tx);
723
748
  if (!result.success) {
724
749
  return this.buildQueryError(result.error);
725
750
  }
726
- return ok(result.data);
751
+ return result;
727
752
  }
728
753
  async countByUserId(userId, tx) {
729
754
  const result = await this.count({ where: "user_id = ?", params: [userId] }, tx);
@@ -1178,11 +1203,11 @@ function createApiKeyStrategy(config) {
1178
1203
  return err(HaiIamError.INTERNAL_ERROR, iamM("iam_apikeyCreateFailed", { params: { message: String(error) } }), error);
1179
1204
  }
1180
1205
  },
1181
- async listApiKeys(userId) {
1182
- const result = await apiKeyRepository.findByUserId(userId);
1206
+ async listApiKeys(userId, options) {
1207
+ const result = await apiKeyRepository.findPageByUserId(userId, options ?? {});
1183
1208
  if (!result.success)
1184
1209
  return result;
1185
- return ok(result.data.map(toApiKey));
1210
+ return ok({ ...result.data, items: result.data.items.map(toApiKey) });
1186
1211
  },
1187
1212
  async getApiKey(keyId) {
1188
1213
  const result = await apiKeyRepository.findOneById(keyId);