@meistrari/auth-core 1.14.0 → 1.16.0

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/dist/index.mjs CHANGED
@@ -8,7 +8,7 @@ import { defaultStatements } from 'better-auth/plugins/organization/access';
8
8
  import { z } from 'zod';
9
9
  export { APIError } from 'better-auth';
10
10
 
11
- const version = "1.14.0";
11
+ const version = "1.16.0";
12
12
 
13
13
  const statements = {
14
14
  ...defaultStatements,
@@ -171,12 +171,17 @@ function applicationsPluginClient() {
171
171
  headers
172
172
  });
173
173
  },
174
- whoAmI: async (accessToken) => {
174
+ whoAmI: async (accessToken, options = {}) => {
175
175
  const headers = new Headers();
176
176
  headers.set("x-tela-access-token", accessToken);
177
+ const query = {};
178
+ if (options.include && options.include.length > 0) {
179
+ query.include = options.include.join(",");
180
+ }
177
181
  return await $fetch("/applications/whoami", {
178
182
  method: "GET",
179
- headers
183
+ headers,
184
+ query
180
185
  });
181
186
  },
182
187
  switchOrganization: async (organizationId, accessToken) => {
@@ -255,7 +260,13 @@ function createAPIClient(apiUrl, fetchOptions = {}) {
255
260
  }
256
261
 
257
262
  class BaseError extends Error {
263
+ /** Machine-readable error code (e.g. `"INVALID_SOCIAL_PROVIDER"`). */
258
264
  code;
265
+ /**
266
+ * @param code - A machine-readable error code
267
+ * @param message - A human-readable error message
268
+ * @param options - Standard `ErrorOptions` (e.g. `cause`)
269
+ */
259
270
  constructor(code, message, options) {
260
271
  super(message, options);
261
272
  this.code = code;
@@ -389,6 +400,16 @@ class ApplicationService {
389
400
  }
390
401
  return response.data;
391
402
  }
403
+ /**
404
+ * Starts a device authorization flow (RFC 8628).
405
+ *
406
+ * Returns a device code and user code that the end user must enter
407
+ * on the verification URI to authorize the device.
408
+ *
409
+ * @param requesterApplicationId - The application requesting authorization
410
+ * @param targetApplicationId - The target application to gain access to
411
+ * @returns Device authorization details including codes and verification URI
412
+ */
392
413
  async startDeviceAuthorizationFlow(requesterApplicationId, targetApplicationId) {
393
414
  const response = await this.client.applications.startDeviceAuthorizationFlow(requesterApplicationId, targetApplicationId);
394
415
  if (!response.data) {
@@ -396,6 +417,15 @@ class ApplicationService {
396
417
  }
397
418
  return response.data;
398
419
  }
420
+ /**
421
+ * Retrieves the context for a pending device authorization request.
422
+ *
423
+ * Used by the authorization page to display details about the requesting
424
+ * and target applications before the user approves or denies.
425
+ *
426
+ * @param userCode - The user code from the device authorization response
427
+ * @returns Context including application info, available organizations, and status
428
+ */
399
429
  async getDeviceAuthorizationContext(userCode) {
400
430
  const response = await this.client.applications.getDeviceAuthorizationContext(userCode);
401
431
  if (!response.data) {
@@ -403,6 +433,13 @@ class ApplicationService {
403
433
  }
404
434
  return response.data;
405
435
  }
436
+ /**
437
+ * Approves a pending device authorization request.
438
+ *
439
+ * @param userCode - The user code identifying the device authorization request
440
+ * @param organizationId - The organization to authorize the device for
441
+ * @returns Confirmation of the approval action
442
+ */
406
443
  async approveDeviceAuthorizationFlow(userCode, organizationId) {
407
444
  const response = await this.client.applications.approveDeviceAuthorizationFlow(userCode, organizationId);
408
445
  if (!response.data) {
@@ -410,6 +447,12 @@ class ApplicationService {
410
447
  }
411
448
  return response.data;
412
449
  }
450
+ /**
451
+ * Denies a pending device authorization request.
452
+ *
453
+ * @param userCode - The user code identifying the device authorization request
454
+ * @returns Confirmation of the denial action
455
+ */
413
456
  async denyDeviceAuthorizationFlow(userCode) {
414
457
  const response = await this.client.applications.denyDeviceAuthorizationFlow(userCode);
415
458
  if (!response.data) {
@@ -417,12 +460,33 @@ class ApplicationService {
417
460
  }
418
461
  return response.data;
419
462
  }
463
+ /**
464
+ * Exchanges a device code for access and refresh tokens.
465
+ *
466
+ * This should be called by the device client while polling. It will throw
467
+ * typed errors to indicate the polling state (pending, slow down, denied, expired).
468
+ *
469
+ * @param deviceCode - The device code obtained from {@link startDeviceAuthorizationFlow}
470
+ * @returns Access and refresh tokens along with user and organization info
471
+ *
472
+ * @throws {DeviceAuthorizationPendingError} The user hasn't authorized yet — keep polling
473
+ * @throws {DeviceAuthorizationSlowDownError} Polling too fast — increase the interval
474
+ * @throws {DeviceAccessDeniedError} The user denied the request
475
+ * @throws {DeviceCodeExpiredError} The device code has expired
476
+ * @throws {DeviceTransientServerError} Transient server error — safe to retry
477
+ */
420
478
  async exchangeDeviceCodeForTokens(deviceCode) {
421
- const response = await this.client.applications.exchangeDeviceCodeForTokens(deviceCode);
422
- if (!response.data) {
423
- throwDeviceGrantError(response.error);
479
+ try {
480
+ const response = await this.client.applications.exchangeDeviceCodeForTokens(deviceCode);
481
+ if (!response.data) {
482
+ throwDeviceGrantError(response.error);
483
+ }
484
+ return response.data;
485
+ } catch (error) {
486
+ if (error instanceof ApplicationError)
487
+ throw error;
488
+ throwDeviceGrantError(error);
424
489
  }
425
- return response.data;
426
490
  }
427
491
  /**
428
492
  * Completes an authorization flow for a specific application.
@@ -445,25 +509,39 @@ class ApplicationService {
445
509
  * @throws {ApplicationError} For other API errors
446
510
  */
447
511
  async refreshAccessToken(refreshToken) {
448
- const response = await this.client.applications.refreshAccessToken(refreshToken);
449
- if (!response.data) {
450
- const error = response.error;
512
+ const handleRefreshError = (error) => {
451
513
  const status = error?.status;
452
514
  if (status === 404) {
453
515
  throw new RefreshTokenExpiredError({ cause: error });
454
516
  }
455
- throw new ApplicationError(error?.message || "Failed to refresh access token", { cause: error });
517
+ const message = error?.message;
518
+ throw new ApplicationError(message || "Failed to refresh access token", { cause: error });
519
+ };
520
+ try {
521
+ const response = await this.client.applications.refreshAccessToken(refreshToken);
522
+ if (!response.data) {
523
+ handleRefreshError(response.error);
524
+ }
525
+ return response.data;
526
+ } catch (error) {
527
+ if (error instanceof ApplicationError)
528
+ throw error;
529
+ handleRefreshError(error);
456
530
  }
457
- return response.data;
458
531
  }
459
532
  /**
460
533
  * Gets the current user and organization for a specific application.
461
534
  *
535
+ * By default, the returned organization does not include its `members`,
536
+ * `teams`, or `invitations` collections. Pass `options.include` to request
537
+ * any of them explicitly.
538
+ *
462
539
  * @param accessToken - The access token to use for the who am I request
540
+ * @param options - Optional include list controlling which relations are loaded
463
541
  * @returns The current user and organization
464
542
  */
465
- async whoAmI(accessToken) {
466
- const response = await this.client.applications.whoAmI(accessToken);
543
+ async whoAmI(accessToken, options = {}) {
544
+ const response = await this.client.applications.whoAmI(accessToken, options);
467
545
  if (!response.data) {
468
546
  throw new Error("No data returned from the API", { cause: response.error });
469
547
  }
@@ -545,10 +623,7 @@ class OrganizationService {
545
623
  /**
546
624
  * Updates an organization's details.
547
625
  *
548
- * @param payload - The organization fields to update
549
- * @param payload.name - New organization name
550
- * @param payload.logo - New organization logo URL
551
- * @param payload.settings - New organization settings
626
+ * @param payload - The organization fields to update (name, logo, settings)
552
627
  * @returns The updated organization
553
628
  */
554
629
  async updateOrganization(payload) {
@@ -623,9 +698,7 @@ class OrganizationService {
623
698
  /**
624
699
  * Removes a user from the active organization.
625
700
  *
626
- * @param options - User identifier (either memberId or userEmail must be provided)
627
- * @param options.memberId - The member ID to remove
628
- * @param options.userEmail - The user email to remove
701
+ * @param options - Provide either `memberId` or `userEmail` to identify the user
629
702
  */
630
703
  async removeUserFromOrganization({ memberId, userEmail }) {
631
704
  await this.client.organization.removeMember({
@@ -648,8 +721,7 @@ class OrganizationService {
648
721
  /**
649
722
  * Creates a new team within the active organization.
650
723
  *
651
- * @param payload - Team configuration
652
- * @param payload.name - The name of the team
724
+ * @param payload - Team configuration with a `name` field
653
725
  * @returns The created team
654
726
  */
655
727
  async createTeam(payload) {
@@ -659,8 +731,7 @@ class OrganizationService {
659
731
  * Updates an existing team's details.
660
732
  *
661
733
  * @param id - The team ID to update
662
- * @param payload - Team fields to update
663
- * @param payload.name - The new team name
734
+ * @param payload - Team fields to update (currently supports `name`)
664
735
  * @returns The updated team
665
736
  */
666
737
  async updateTeam(id, payload) {
@@ -919,6 +990,15 @@ class ApiKeyService {
919
990
  constructor(client) {
920
991
  this.client = client;
921
992
  }
993
+ /**
994
+ * Creates a new API key.
995
+ *
996
+ * The returned object includes the secret `key` value, which is only
997
+ * available at creation time and cannot be retrieved later.
998
+ *
999
+ * @param payload - The API key configuration
1000
+ * @returns The created API key including the secret key value
1001
+ */
922
1002
  async createApiKey(payload) {
923
1003
  return await this.client.apiKey.create({
924
1004
  name: payload.name,
@@ -927,6 +1007,12 @@ class ApiKeyService {
927
1007
  metadata: payload.metadata
928
1008
  });
929
1009
  }
1010
+ /**
1011
+ * Retrieves an API key by its ID.
1012
+ *
1013
+ * @param id - The API key ID
1014
+ * @returns The API key (without the secret key value)
1015
+ */
930
1016
  async getApiKey(id) {
931
1017
  return await this.client.apiKey.get({
932
1018
  query: {
@@ -934,18 +1020,39 @@ class ApiKeyService {
934
1020
  }
935
1021
  });
936
1022
  }
1023
+ /**
1024
+ * Lists all API keys owned by the authenticated user.
1025
+ *
1026
+ * @returns An object containing the API keys array and pagination metadata
1027
+ */
937
1028
  async listApiKeys() {
938
1029
  return await this.client.apiKey.list();
939
1030
  }
1031
+ /**
1032
+ * Lists all API keys belonging to the active organization.
1033
+ *
1034
+ * @returns An array of API keys (without secret key values)
1035
+ */
940
1036
  async listOrganizationApiKeys() {
941
1037
  return await this.client.customEndpoints.organizations.apiKeys();
942
1038
  }
1039
+ /**
1040
+ * Updates an existing API key.
1041
+ *
1042
+ * @param payload - The fields to update
1043
+ * @returns The updated API key (without the secret key value)
1044
+ */
943
1045
  async updateApiKey(payload) {
944
1046
  return await this.client.apiKey.update({
945
1047
  keyId: payload.id,
946
1048
  name: payload.name
947
1049
  });
948
1050
  }
1051
+ /**
1052
+ * Permanently deletes an API key.
1053
+ *
1054
+ * @param id - The API key ID to delete
1055
+ */
949
1056
  async deleteApiKey(id) {
950
1057
  return await this.client.apiKey.delete({
951
1058
  keyId: id
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meistrari/auth-core",
3
- "version": "1.14.0",
3
+ "version": "1.16.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -14,7 +14,8 @@
14
14
  "dist"
15
15
  ],
16
16
  "scripts": {
17
- "build": "unbuild"
17
+ "build": "unbuild",
18
+ "docs": "typedoc"
18
19
  },
19
20
  "dependencies": {
20
21
  "@better-auth/api-key": "1.5.4",
@@ -25,6 +26,8 @@
25
26
  },
26
27
  "devDependencies": {
27
28
  "@types/node": "latest",
29
+ "typedoc": "0.28.18",
30
+ "typedoc-plugin-markdown": "4.11.0",
28
31
  "typescript": "5.9.2",
29
32
  "unbuild": "3.6.1"
30
33
  }