@authup/server-core 1.0.0-beta.60 → 1.0.0-beta.62

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.
Files changed (172) hide show
  1. package/dist/adapters/database/domains/client-scope/entity.d.ts.map +1 -1
  2. package/dist/adapters/database/domains/client-scope/entity.mjs +16 -8
  3. package/dist/adapters/database/domains/client-scope/entity.mjs.map +1 -1
  4. package/dist/adapters/database/domains/identity-provider-account/entity.d.ts.map +1 -1
  5. package/dist/adapters/database/domains/identity-provider-account/entity.mjs +1 -1
  6. package/dist/adapters/database/domains/identity-provider-account/entity.mjs.map +1 -1
  7. package/dist/adapters/database/migrations/mysql/1786631686318-SortIndexesAndAccountUniqueness.d.ts +50 -0
  8. package/dist/adapters/database/migrations/mysql/1786631686318-SortIndexesAndAccountUniqueness.d.ts.map +1 -0
  9. package/dist/adapters/database/migrations/mysql/1786631686318-SortIndexesAndAccountUniqueness.mjs +86 -0
  10. package/dist/adapters/database/migrations/mysql/1786631686318-SortIndexesAndAccountUniqueness.mjs.map +1 -0
  11. package/dist/adapters/database/migrations/postgres/1786631686318-SortIndexesAndAccountUniqueness.d.ts +42 -0
  12. package/dist/adapters/database/migrations/postgres/1786631686318-SortIndexesAndAccountUniqueness.d.ts.map +1 -0
  13. package/dist/adapters/database/migrations/postgres/1786631686318-SortIndexesAndAccountUniqueness.mjs +80 -0
  14. package/dist/adapters/database/migrations/postgres/1786631686318-SortIndexesAndAccountUniqueness.mjs.map +1 -0
  15. package/dist/adapters/http/adapters/oauth2/grant-types/utils/credentials.mjs +1 -1
  16. package/dist/adapters/http/adapters/oauth2/grant-types/utils/guess.mjs +1 -1
  17. package/dist/adapters/http/controllers/entities/client/module.mjs +2 -2
  18. package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts +12 -8
  19. package/dist/adapters/http/controllers/entities/identity-provider/module.d.ts.map +1 -1
  20. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs +137 -88
  21. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs.map +1 -1
  22. package/dist/adapters/http/controllers/entities/identity-provider/types.d.ts +7 -5
  23. package/dist/adapters/http/controllers/entities/identity-provider/types.d.ts.map +1 -1
  24. package/dist/adapters/http/controllers/entities/realm/module.mjs +2 -2
  25. package/dist/adapters/http/controllers/entities/session/module.mjs +2 -2
  26. package/dist/adapters/http/controllers/entities/user/module.mjs +2 -2
  27. package/dist/adapters/http/controllers/entities/user-authenticator/module.mjs +2 -2
  28. package/dist/adapters/http/controllers/workflows/authorize/module.d.ts.map +1 -1
  29. package/dist/adapters/http/controllers/workflows/authorize/module.mjs +9 -5
  30. package/dist/adapters/http/controllers/workflows/authorize/module.mjs.map +1 -1
  31. package/dist/adapters/http/controllers/workflows/token/utils/extract.mjs +2 -1
  32. package/dist/adapters/http/controllers/workflows/token/utils/extract.mjs.map +1 -1
  33. package/dist/adapters/http/middleware/built-in/assets.mjs +1 -1
  34. package/dist/adapters/http/request/helpers/param-id.d.ts.map +1 -1
  35. package/dist/adapters/http/request/helpers/param-id.mjs +2 -1
  36. package/dist/adapters/http/request/helpers/param-id.mjs.map +1 -1
  37. package/dist/adapters/http/ui/account-console/module.mjs +1 -1
  38. package/dist/adapters/http/ui/auth-console/http-client.mjs +1 -1
  39. package/dist/adapters/http/ui/auth-console/module.mjs +1 -1
  40. package/dist/adapters/http/ui/console-packages/module.d.ts +1 -1
  41. package/dist/adapters/http/ui/console-packages/module.mjs +2 -2
  42. package/dist/adapters/http/ui/console-packages/module.mjs.map +1 -1
  43. package/dist/adapters/http/ui/shared/html.d.ts.map +1 -1
  44. package/dist/adapters/http/ui/shared/html.mjs +1 -0
  45. package/dist/adapters/http/ui/shared/html.mjs.map +1 -1
  46. package/dist/app/index.mjs +3 -1
  47. package/dist/app/modules/config/read/env.mjs +1 -1
  48. package/dist/app/modules/database/repositories/event/repository.d.ts +2 -2
  49. package/dist/app/modules/database/repositories/event/repository.d.ts.map +1 -1
  50. package/dist/app/modules/database/repositories/event/repository.mjs +23 -6
  51. package/dist/app/modules/database/repositories/event/repository.mjs.map +1 -1
  52. package/dist/app/modules/database/repositories/identity-provider-account/repository.d.ts.map +1 -1
  53. package/dist/app/modules/database/repositories/identity-provider-account/repository.mjs +9 -1
  54. package/dist/app/modules/database/repositories/identity-provider-account/repository.mjs.map +1 -1
  55. package/dist/app/modules/http/modules/controller.d.ts.map +1 -1
  56. package/dist/app/modules/http/modules/controller.mjs +18 -6
  57. package/dist/app/modules/http/modules/controller.mjs.map +1 -1
  58. package/dist/app/modules/identity/constants.d.ts +2 -1
  59. package/dist/app/modules/identity/constants.d.ts.map +1 -1
  60. package/dist/app/modules/identity/constants.mjs +1 -0
  61. package/dist/app/modules/identity/constants.mjs.map +1 -1
  62. package/dist/app/modules/identity/index.mjs +3 -1
  63. package/dist/app/modules/identity/module.d.ts.map +1 -1
  64. package/dist/app/modules/identity/module.mjs +13 -3
  65. package/dist/app/modules/identity/module.mjs.map +1 -1
  66. package/dist/app/modules/identity/repositories/constants.d.ts +4 -0
  67. package/dist/app/modules/identity/repositories/constants.d.ts.map +1 -0
  68. package/dist/app/modules/identity/repositories/constants.mjs +12 -0
  69. package/dist/app/modules/identity/repositories/constants.mjs.map +1 -0
  70. package/dist/app/modules/identity/repositories/index.d.ts +1 -0
  71. package/dist/app/modules/identity/repositories/index.d.ts.map +1 -1
  72. package/dist/app/modules/identity/repositories/index.mjs +3 -1
  73. package/dist/app/modules/identity/repositories/provider/index.d.ts +1 -0
  74. package/dist/app/modules/identity/repositories/provider/index.d.ts.map +1 -1
  75. package/dist/app/modules/identity/repositories/provider/index.mjs +2 -1
  76. package/dist/app/modules/identity/repositories/provider/link.d.ts +9 -0
  77. package/dist/app/modules/identity/repositories/provider/link.d.ts.map +1 -0
  78. package/dist/app/modules/identity/repositories/provider/link.mjs +34 -0
  79. package/dist/app/modules/identity/repositories/provider/link.mjs.map +1 -0
  80. package/dist/app/modules/identity/repositories/user.d.ts +1 -0
  81. package/dist/app/modules/identity/repositories/user.d.ts.map +1 -1
  82. package/dist/app/modules/identity/repositories/user.mjs +3 -0
  83. package/dist/app/modules/identity/repositories/user.mjs.map +1 -1
  84. package/dist/app/modules/index.mjs +3 -1
  85. package/dist/app/modules/oauth2/repositories/authorize/state/repository.d.ts +1 -2
  86. package/dist/app/modules/oauth2/repositories/authorize/state/repository.d.ts.map +1 -1
  87. package/dist/app/modules/oauth2/repositories/authorize/state/repository.mjs +7 -16
  88. package/dist/app/modules/oauth2/repositories/authorize/state/repository.mjs.map +1 -1
  89. package/dist/app/modules/runtime/module.mjs +2 -2
  90. package/dist/cli/commands/migration.mjs +1 -1
  91. package/dist/core/entities/client-scope/schema.d.ts.map +1 -1
  92. package/dist/core/entities/client-scope/schema.mjs +16 -1
  93. package/dist/core/entities/client-scope/schema.mjs.map +1 -1
  94. package/dist/core/entities/event/constants.d.ts +9 -0
  95. package/dist/core/entities/event/constants.d.ts.map +1 -1
  96. package/dist/core/entities/event/constants.mjs +9 -1
  97. package/dist/core/entities/event/constants.mjs.map +1 -1
  98. package/dist/core/entities/event/index.mjs +2 -2
  99. package/dist/core/entities/event/types.d.ts +11 -2
  100. package/dist/core/entities/event/types.d.ts.map +1 -1
  101. package/dist/core/entities/identity-provider-account/types.d.ts +6 -0
  102. package/dist/core/entities/identity-provider-account/types.d.ts.map +1 -1
  103. package/dist/core/entities/identity-provider-account/types.mjs.map +1 -1
  104. package/dist/core/entities/index.mjs +2 -2
  105. package/dist/core/identity/entities/user/types.d.ts +1 -0
  106. package/dist/core/identity/entities/user/types.d.ts.map +1 -1
  107. package/dist/core/identity/index.mjs +12 -11
  108. package/dist/core/identity/provider/account/constants.d.ts +10 -0
  109. package/dist/core/identity/provider/account/constants.d.ts.map +1 -0
  110. package/dist/core/identity/provider/account/constants.mjs +16 -0
  111. package/dist/core/identity/provider/account/constants.mjs.map +1 -0
  112. package/dist/core/identity/provider/account/index.d.ts +1 -0
  113. package/dist/core/identity/provider/account/index.d.ts.map +1 -1
  114. package/dist/core/identity/provider/account/index.mjs +2 -1
  115. package/dist/core/identity/provider/account/module.d.ts +3 -0
  116. package/dist/core/identity/provider/account/module.d.ts.map +1 -1
  117. package/dist/core/identity/provider/account/module.mjs +54 -27
  118. package/dist/core/identity/provider/account/module.mjs.map +1 -1
  119. package/dist/core/identity/provider/account/types.d.ts +42 -0
  120. package/dist/core/identity/provider/account/types.d.ts.map +1 -1
  121. package/dist/core/identity/provider/authentication/index.mjs +1 -1
  122. package/dist/core/identity/provider/authentication/protocols/oauth2/module.d.ts +18 -0
  123. package/dist/core/identity/provider/authentication/protocols/oauth2/module.d.ts.map +1 -1
  124. package/dist/core/identity/provider/authentication/protocols/oauth2/module.mjs +55 -2
  125. package/dist/core/identity/provider/authentication/protocols/oauth2/module.mjs.map +1 -1
  126. package/dist/core/identity/provider/authentication/protocols/oauth2/types.d.ts +2 -0
  127. package/dist/core/identity/provider/authentication/protocols/oauth2/types.d.ts.map +1 -1
  128. package/dist/core/identity/provider/authentication/protocols/open-id/module.d.ts +0 -3
  129. package/dist/core/identity/provider/authentication/protocols/open-id/module.d.ts.map +1 -1
  130. package/dist/core/identity/provider/authentication/protocols/open-id/module.mjs +0 -17
  131. package/dist/core/identity/provider/authentication/protocols/open-id/module.mjs.map +1 -1
  132. package/dist/core/identity/provider/index.mjs +12 -11
  133. package/dist/core/index.mjs +15 -12
  134. package/dist/core/oauth2/authorization/code-request/verifier/module.d.ts.map +1 -1
  135. package/dist/core/oauth2/authorization/code-request/verifier/module.mjs +9 -2
  136. package/dist/core/oauth2/authorization/code-request/verifier/module.mjs.map +1 -1
  137. package/dist/core/oauth2/authorization/state/module.mjs +1 -2
  138. package/dist/core/oauth2/authorization/state/module.mjs.map +1 -1
  139. package/dist/core/oauth2/authorization/state/types.d.ts +5 -2
  140. package/dist/core/oauth2/authorization/state/types.d.ts.map +1 -1
  141. package/dist/core/oauth2/end-session/service.d.ts.map +1 -1
  142. package/dist/core/oauth2/end-session/service.mjs +1 -0
  143. package/dist/core/oauth2/end-session/service.mjs.map +1 -1
  144. package/dist/core/oauth2/federated-login/index.d.ts +3 -0
  145. package/dist/core/oauth2/federated-login/index.d.ts.map +1 -0
  146. package/dist/core/oauth2/federated-login/index.mjs +6 -0
  147. package/dist/core/oauth2/federated-login/module.d.ts +20 -0
  148. package/dist/core/oauth2/federated-login/module.d.ts.map +1 -0
  149. package/dist/core/oauth2/federated-login/module.mjs +137 -0
  150. package/dist/core/oauth2/federated-login/module.mjs.map +1 -0
  151. package/dist/core/oauth2/federated-login/types.d.ts +138 -0
  152. package/dist/core/oauth2/federated-login/types.d.ts.map +1 -0
  153. package/dist/core/oauth2/federated-login/types.mjs +31 -0
  154. package/dist/core/oauth2/federated-login/types.mjs.map +1 -0
  155. package/dist/core/oauth2/index.d.ts +1 -0
  156. package/dist/core/oauth2/index.d.ts.map +1 -1
  157. package/dist/core/oauth2/index.mjs +4 -1
  158. package/dist/core/provisioning/entities/policy/validator.d.ts.map +1 -1
  159. package/dist/core/provisioning/entities/policy/validator.mjs +2 -1
  160. package/dist/core/provisioning/entities/policy/validator.mjs.map +1 -1
  161. package/dist/core/provisioning/entities/realm/wildcard-validator.d.ts.map +1 -1
  162. package/dist/core/provisioning/entities/realm/wildcard-validator.mjs +2 -1
  163. package/dist/core/provisioning/entities/realm/wildcard-validator.mjs.map +1 -1
  164. package/dist/core/security/policy/evaluator.mjs.map +1 -1
  165. package/dist/index.mjs +3 -1
  166. package/dist/node_modules/@ebec/core/dist/index.mjs +130 -0
  167. package/dist/node_modules/@ebec/core/dist/index.mjs.map +1 -0
  168. package/dist/swagger.json +146 -18
  169. package/dist/utils/error.d.ts.map +1 -1
  170. package/dist/utils/error.mjs +5 -6
  171. package/dist/utils/error.mjs.map +1 -1
  172. package/package.json +28 -28
package/dist/index.mjs CHANGED
@@ -210,6 +210,8 @@ import { IdentityInjectionKey } from "./app/modules/identity/constants.mjs";
210
210
  import { IdentityProviderAttributeMappingRepository } from "./app/modules/identity/repositories/provider/mapper/attribute.mjs";
211
211
  import { IdentityProviderPermissionMappingRepository } from "./app/modules/identity/repositories/provider/mapper/permission.mjs";
212
212
  import { IdentityProviderRoleMappingRepository } from "./app/modules/identity/repositories/provider/mapper/role.mjs";
213
+ import { CacheIdentityPrefix } from "./app/modules/identity/repositories/constants.mjs";
214
+ import { IdentityProviderAccountLinkStore } from "./app/modules/identity/repositories/provider/link.mjs";
213
215
  import { ClientIdentityRepository } from "./app/modules/identity/repositories/client.mjs";
214
216
  import { UserIdentityRepository } from "./app/modules/identity/repositories/user.mjs";
215
217
  import { LDAPInjectionKey } from "./app/modules/ldap/constants.mjs";
@@ -234,4 +236,4 @@ import { defineCLIMigrationCommand } from "./cli/commands/migration.mjs";
234
236
  import { defineCLIStartCommand } from "./cli/commands/start.mjs";
235
237
  import "./cli/commands/index.mjs";
236
238
  import "reflect-metadata";
237
- export { AccountController, ActivateController, ApplicationBuilder, AuthenticationInjectionKey, AuthenticationModule, AuthenticatorChallengeController, AuthorizationMiddleware, AuthorizeController, CERTIFICATE_SOURCES, CacheInjectionKey, CacheModule, CachePrefix, ClientController, ClientEntity, ClientIdentityRepository, ClientPermissionController, ClientPermissionEntity, ClientPermissionRepositoryAdapter, ClientPermissionRequestValidator, ClientPermissionSubscriber, ClientRepositoryAdapter, ClientRoleController, ClientRoleEntity, ClientRoleRepositoryAdapter, ClientRoleRequestValidator, ClientRoleSubscriber, ClientScopeController, ClientScopeEntity, ClientScopeRepositoryAdapter, ClientScopeRequestValidator, ClientScopeSubscriber, ClientSubscriber, ComponentsModule, CompositeProvisioningSource, ConfigEnvironmentVariableName, ConfigInjectionKey, ConfigModule, ConsentController, ConsentEntity, ConsentEntitySubscriber, DataSourceOptionsBuilder, DatabaseConflictError, DatabaseInjectionKey, DatabaseModule, DatabaseQueryResultCache, DefaultProvisioningSource, EntitySubscriber, EventController, EventEntity, EventRepositoryAdapter, FileProvisioningSource, ForceLoggedInMiddleware, ForceUserLoggedInMiddleware, HTTPClientCredentialsGrant, HTTPInjectionKey, HTTPModule, HTTPOAuth2AuthorizeGrant, HTTPOAuth2Authorizer, HTTPOAuth2IdentityGrantType, HTTPOAuth2RefreshTokenGrant, HTTPPasswordGrant, IdentityInjectionKey, IdentityModule, IdentityProviderAccountController, IdentityProviderAccountEntity, IdentityProviderAccountRepositoryAdapter, IdentityProviderAccountSubscriber, IdentityProviderAttributeEntity, IdentityProviderAttributeMappingEntity, IdentityProviderAttributeMappingRepository, IdentityProviderAttributeSubscriber, IdentityProviderController, IdentityProviderEntity, IdentityProviderPermissionMappingEntity, IdentityProviderPermissionMappingRepository, IdentityProviderRepository, IdentityProviderRepositoryAdapter, IdentityProviderRoleMappingController, IdentityProviderRoleMappingEntity, IdentityProviderRoleMappingRepository, IdentityProviderRoleMappingRepositoryAdapter, IdentityProviderRoleSubscriber, IdentityProviderSubscriber, JwkController, KeyController, KeyEntity, KeyRepositoryAdapter, LDAPInjectionKey, LOCALE_COOKIE, LazyWildcardRealmProvisioner, LdapModule, LoggerInjectionKey, LoggerModule, LogoutController, MailInjectionKey, MailModule, MailTemplateRendererInjectionKey, MetricsInjectionKey, ModuleName, OAuth2InjectionToken, OAuth2Module, OpenIDController, PasswordForgotController, PasswordResetController, PermissionController, PermissionDatabaseProvider, PermissionEntity, PermissionPolicyController, PermissionPolicyEntity, PermissionPolicyRepositoryAdapter, PermissionRepositoryAdapter, PermissionSubscriber, PolicyAttributeEntity, PolicyAttributeSubscriber, PolicyAttributesValidator, PolicyController, PolicyEntity, PolicyRepository, PolicyRepositoryAdapter, PolicySubscriber, PolicyValidator, PromAuthFlowMetrics, ProvisionerModule, ProvisioningInjectionKey, RealmController, RealmEntity, RealmRepository, RealmRepositoryAdapter, RealmResolverMiddleware, RealmSubscriber, RegisterController, RequestHandlerOperation, RequestIdentity, RequestPermissionEvaluator, RoleAttributeController, RoleAttributeEntity, RoleAttributeRepositoryAdapter, RoleAttributeRequestValidator, RoleAttributeSubscriber, RoleController, RoleEntity, RolePermissionController, RolePermissionEntity, RolePermissionRepositoryAdapter, RolePermissionRequestValidator, RolePermissionSubscriber, RoleRepository, RoleRepositoryAdapter, RoleSubscriber, RuntimeModule, ScopeController, ScopeEntity, ScopeRepositoryAdapter, ScopeSubscriber, SessionController, SessionEntity, SessionRepository, SessionTokenController, SessionTokenEntity, StatusController, THEME_STORE_KEY, TokenController, TrustAnchorController, TrustAnchorEntity, TrustAnchorRepositoryAdapter, UI_HTTP_CLIENT_FACTORY_STORE_KEY, UserAttributeController, UserAttributeEntity, UserAttributeRepositoryAdapter, UserAttributeRequestValidator, UserAttributeSubscriber, UserAuthenticatorController, UserAuthenticatorEntity, UserAuthenticatorRepositoryAdapter, UserController, UserEntity, UserIdentityRepository, UserInfoController, UserPermissionController, UserPermissionEntity, UserPermissionRepositoryAdapter, UserPermissionRequestValidator, UserPermissionSubscriber, UserRepository, UserRepositoryAdapter, UserRoleController, UserRoleEntity, UserRoleRepositoryAdapter, UserRoleRequestValidator, UserRoleSubscriber, UserSubscriber, VITE_SERVER_STORE_KEY, applyRouteRealmIDToBody, buildActorContext, buildEntityDestinations, createApplication, createAuthorizationMiddleware, createLoggerMiddleware, createRealmResolverMiddleware, createRequestEventContextMiddleware, createRouteTemplateNormalizePath, createSwaggerMiddleware, dateToISOStringTransformer, defineCLIHealthCheckCommand, defineCLIMigrationCommand, defineCLIStartCommand, expandToOrigins, extractClientCertificateEvidence, extractClientCredentialsFromRequest, extractOAuth2ClientCertificateEvidence, getAppOrigins, getBodyRealmID, getDatabaseDriverErrorCode, getJwkRouteHandler, getJwksRouteHandler, getRequestParamID, getRequestRealmID, getRequestStringParam, getRequestStringParamOrFail, guessOauth2GrantTypeByRequest, isDatabaseTypeRowLockable, isDatabaseTypeSupported, isDatabaseTypeSupportedForEnvironment, isForeignKeyConstraintDatabaseError, isUniqueConstraintDatabaseError, readConfig, readConfigRaw, readConfigRawFromEnv, readConfigRawFromFS, readFromLocations, readRealmHint, readStringField, redactSensitiveURLParams, registerAssetsMiddleware, registerBasicMiddleware, registerCorsMiddleware, registerErrorMiddleware, registerPrometheusMiddleware, registerRateLimitMiddleware, registerThemeMiddleware, registerUIHttpClientMiddleware, runWithRequestEventContext, sanitizeRelativeRedirect, setRequestIdentity, setRequestMfaLoginTicket, setRequestPermissionEvaluator, setRequestRealmID, setRequestScopes, setRequestSessionId, setRequestToken, useRequestEventContext, useRequestIdentity, useRequestIdentityOrFail, useRequestLocale, useRequestMfaLoginTicket, useRequestParamID, useRequestPermissionEvaluator, useRequestScopes, useRequestSessionId, useRequestTheme, useRequestToken };
239
+ export { AccountController, ActivateController, ApplicationBuilder, AuthenticationInjectionKey, AuthenticationModule, AuthenticatorChallengeController, AuthorizationMiddleware, AuthorizeController, CERTIFICATE_SOURCES, CacheIdentityPrefix, CacheInjectionKey, CacheModule, CachePrefix, ClientController, ClientEntity, ClientIdentityRepository, ClientPermissionController, ClientPermissionEntity, ClientPermissionRepositoryAdapter, ClientPermissionRequestValidator, ClientPermissionSubscriber, ClientRepositoryAdapter, ClientRoleController, ClientRoleEntity, ClientRoleRepositoryAdapter, ClientRoleRequestValidator, ClientRoleSubscriber, ClientScopeController, ClientScopeEntity, ClientScopeRepositoryAdapter, ClientScopeRequestValidator, ClientScopeSubscriber, ClientSubscriber, ComponentsModule, CompositeProvisioningSource, ConfigEnvironmentVariableName, ConfigInjectionKey, ConfigModule, ConsentController, ConsentEntity, ConsentEntitySubscriber, DataSourceOptionsBuilder, DatabaseConflictError, DatabaseInjectionKey, DatabaseModule, DatabaseQueryResultCache, DefaultProvisioningSource, EntitySubscriber, EventController, EventEntity, EventRepositoryAdapter, FileProvisioningSource, ForceLoggedInMiddleware, ForceUserLoggedInMiddleware, HTTPClientCredentialsGrant, HTTPInjectionKey, HTTPModule, HTTPOAuth2AuthorizeGrant, HTTPOAuth2Authorizer, HTTPOAuth2IdentityGrantType, HTTPOAuth2RefreshTokenGrant, HTTPPasswordGrant, IdentityInjectionKey, IdentityModule, IdentityProviderAccountController, IdentityProviderAccountEntity, IdentityProviderAccountLinkStore, IdentityProviderAccountRepositoryAdapter, IdentityProviderAccountSubscriber, IdentityProviderAttributeEntity, IdentityProviderAttributeMappingEntity, IdentityProviderAttributeMappingRepository, IdentityProviderAttributeSubscriber, IdentityProviderController, IdentityProviderEntity, IdentityProviderPermissionMappingEntity, IdentityProviderPermissionMappingRepository, IdentityProviderRepository, IdentityProviderRepositoryAdapter, IdentityProviderRoleMappingController, IdentityProviderRoleMappingEntity, IdentityProviderRoleMappingRepository, IdentityProviderRoleMappingRepositoryAdapter, IdentityProviderRoleSubscriber, IdentityProviderSubscriber, JwkController, KeyController, KeyEntity, KeyRepositoryAdapter, LDAPInjectionKey, LOCALE_COOKIE, LazyWildcardRealmProvisioner, LdapModule, LoggerInjectionKey, LoggerModule, LogoutController, MailInjectionKey, MailModule, MailTemplateRendererInjectionKey, MetricsInjectionKey, ModuleName, OAuth2InjectionToken, OAuth2Module, OpenIDController, PasswordForgotController, PasswordResetController, PermissionController, PermissionDatabaseProvider, PermissionEntity, PermissionPolicyController, PermissionPolicyEntity, PermissionPolicyRepositoryAdapter, PermissionRepositoryAdapter, PermissionSubscriber, PolicyAttributeEntity, PolicyAttributeSubscriber, PolicyAttributesValidator, PolicyController, PolicyEntity, PolicyRepository, PolicyRepositoryAdapter, PolicySubscriber, PolicyValidator, PromAuthFlowMetrics, ProvisionerModule, ProvisioningInjectionKey, RealmController, RealmEntity, RealmRepository, RealmRepositoryAdapter, RealmResolverMiddleware, RealmSubscriber, RegisterController, RequestHandlerOperation, RequestIdentity, RequestPermissionEvaluator, RoleAttributeController, RoleAttributeEntity, RoleAttributeRepositoryAdapter, RoleAttributeRequestValidator, RoleAttributeSubscriber, RoleController, RoleEntity, RolePermissionController, RolePermissionEntity, RolePermissionRepositoryAdapter, RolePermissionRequestValidator, RolePermissionSubscriber, RoleRepository, RoleRepositoryAdapter, RoleSubscriber, RuntimeModule, ScopeController, ScopeEntity, ScopeRepositoryAdapter, ScopeSubscriber, SessionController, SessionEntity, SessionRepository, SessionTokenController, SessionTokenEntity, StatusController, THEME_STORE_KEY, TokenController, TrustAnchorController, TrustAnchorEntity, TrustAnchorRepositoryAdapter, UI_HTTP_CLIENT_FACTORY_STORE_KEY, UserAttributeController, UserAttributeEntity, UserAttributeRepositoryAdapter, UserAttributeRequestValidator, UserAttributeSubscriber, UserAuthenticatorController, UserAuthenticatorEntity, UserAuthenticatorRepositoryAdapter, UserController, UserEntity, UserIdentityRepository, UserInfoController, UserPermissionController, UserPermissionEntity, UserPermissionRepositoryAdapter, UserPermissionRequestValidator, UserPermissionSubscriber, UserRepository, UserRepositoryAdapter, UserRoleController, UserRoleEntity, UserRoleRepositoryAdapter, UserRoleRequestValidator, UserRoleSubscriber, UserSubscriber, VITE_SERVER_STORE_KEY, applyRouteRealmIDToBody, buildActorContext, buildEntityDestinations, createApplication, createAuthorizationMiddleware, createLoggerMiddleware, createRealmResolverMiddleware, createRequestEventContextMiddleware, createRouteTemplateNormalizePath, createSwaggerMiddleware, dateToISOStringTransformer, defineCLIHealthCheckCommand, defineCLIMigrationCommand, defineCLIStartCommand, expandToOrigins, extractClientCertificateEvidence, extractClientCredentialsFromRequest, extractOAuth2ClientCertificateEvidence, getAppOrigins, getBodyRealmID, getDatabaseDriverErrorCode, getJwkRouteHandler, getJwksRouteHandler, getRequestParamID, getRequestRealmID, getRequestStringParam, getRequestStringParamOrFail, guessOauth2GrantTypeByRequest, isDatabaseTypeRowLockable, isDatabaseTypeSupported, isDatabaseTypeSupportedForEnvironment, isForeignKeyConstraintDatabaseError, isUniqueConstraintDatabaseError, readConfig, readConfigRaw, readConfigRawFromEnv, readConfigRawFromFS, readFromLocations, readRealmHint, readStringField, redactSensitiveURLParams, registerAssetsMiddleware, registerBasicMiddleware, registerCorsMiddleware, registerErrorMiddleware, registerPrometheusMiddleware, registerRateLimitMiddleware, registerThemeMiddleware, registerUIHttpClientMiddleware, runWithRequestEventContext, sanitizeRelativeRedirect, setRequestIdentity, setRequestMfaLoginTicket, setRequestPermissionEvaluator, setRequestRealmID, setRequestScopes, setRequestSessionId, setRequestToken, useRequestEventContext, useRequestIdentity, useRequestIdentityOrFail, useRequestLocale, useRequestMfaLoginTicket, useRequestParamID, useRequestPermissionEvaluator, useRequestScopes, useRequestSessionId, useRequestTheme, useRequestToken };
@@ -0,0 +1,130 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ //#region ../../node_modules/@ebec/core/dist/index.mjs
5
+ /**
6
+ * Vocabulary of well-known issue codes. Validators map their own failure
7
+ * kinds onto these so consumer-side translation catalogs can ship one
8
+ * localized message per code instead of falling back to a generic
9
+ * "invalid value".
10
+ *
11
+ * Tracks the common ground between vuelidate, zod, joi, yup and
12
+ * validator.js. The list lifts from vuelidate's catalog (snake_cased);
13
+ * modern format codes (`PATTERN`, `UUID`, `DATE`, `JSON`, `BASE64`,
14
+ * `STRONG_PASSWORD`, …) cover ground vuelidate predates. Every format
15
+ * code names the format positively (`UUID`, `EMAIL`, `URL`, …) rather
16
+ * than the failure mode (`NOT_UUID`, `INVALID_EMAIL`) so the registry
17
+ * reads consistently.
18
+ *
19
+ * **This vocabulary is a default, not a requirement.** `IssueItem.code`
20
+ * is widened to `IssueCode | (string & {})`, so a library with its own
21
+ * vocabulary — `rapiq`'s `key_not_allowed`, an app's `email_taken` —
22
+ * emits well-formed issues without touching this const at all. If you
23
+ * want a typed const for your own codes, define one alongside this one:
24
+ *
25
+ * ```ts
26
+ * import { IssueCode } from '@ebec/core';
27
+ *
28
+ * export const AppCode = {
29
+ * ...IssueCode,
30
+ * EMAIL_TAKEN: 'email_taken',
31
+ * } as const;
32
+ * ```
33
+ *
34
+ * Each entry's JSDoc documents the structured `data` producers should
35
+ * attach when constructing the issue — templates can rely on those
36
+ * placeholders being present (`{min}`, `{max}`, `{other}`, etc.).
37
+ */
38
+ const IssueCode = {
39
+ /** Generic fallback when no more-specific code applies. `data`: — */
40
+ VALUE_INVALID: "value_invalid",
41
+ /** Every branch of a `oneOf` alternative failed. `data`: — */
42
+ ONE_OF_FAILED: "one_of_failed",
43
+ /** Value is missing, `undefined`, `null`, or empty per the validator's semantics. `data`: — */
44
+ REQUIRED: "required",
45
+ /** Value contains characters outside the alphabetical set. `data`: — */
46
+ ALPHA: "alpha",
47
+ /** Value contains characters outside the alphanumeric set. `data`: — */
48
+ ALPHA_NUM: "alpha_num",
49
+ /** Value is not a number. `data`: — */
50
+ NUMERIC: "numeric",
51
+ /** Value is not an integer. `data`: — */
52
+ INTEGER: "integer",
53
+ /** Value is not a decimal number. `data`: — */
54
+ DECIMAL: "decimal",
55
+ /** Value is shorter than the configured minimum. `data`: `{ min: number }` */
56
+ MIN_LENGTH: "min_length",
57
+ /** Value is longer than the configured maximum. `data`: `{ max: number }` */
58
+ MAX_LENGTH: "max_length",
59
+ /** Numeric value is below the configured minimum. `data`: `{ min: number }` */
60
+ MIN_VALUE: "min_value",
61
+ /** Numeric value is above the configured maximum. `data`: `{ max: number }` */
62
+ MAX_VALUE: "max_value",
63
+ /** Numeric value falls outside the configured `[min, max]` range. `data`: `{ min: number, max: number }` */
64
+ BETWEEN: "between",
65
+ /** Value is not a valid email address. `data`: — */
66
+ EMAIL: "email",
67
+ /** Value is not a valid URL. `data`: — */
68
+ URL: "url",
69
+ /** Value is not a valid IP address. `data`: — */
70
+ IP_ADDRESS: "ip_address",
71
+ /** Value is not a valid MAC address. `data`: — */
72
+ MAC_ADDRESS: "mac_address",
73
+ /** Value is not a valid UUID. `data`: — */
74
+ UUID: "uuid",
75
+ /** Value is not a valid date / cannot be parsed as a date. `data`: — */
76
+ DATE: "date",
77
+ /**
78
+ * Value does not match the expected regex pattern. `data`:
79
+ * `{ pattern: string }` — source of the regex without flags so
80
+ * catalogs can quote it in human-readable form.
81
+ */
82
+ PATTERN: "pattern",
83
+ /** Value is not valid JSON. `data`: — */
84
+ JSON: "json",
85
+ /** Value is not valid base64. `data`: — */
86
+ BASE64: "base64",
87
+ /**
88
+ * Value does not meet the configured strong-password rules. `data`:
89
+ * `{ minLength?: number, minLowercase?: number, minUppercase?: number,
90
+ * minNumbers?: number, minSymbols?: number }` — only the keys the
91
+ * producer chose to surface; missing keys mean "the default for that
92
+ * setting wasn't configured."
93
+ */
94
+ STRONG_PASSWORD: "strong_password",
95
+ /**
96
+ * Value must equal another named field's value (sibling-field assertion,
97
+ * e.g. password-confirm). `data`: `{ other: string }` — the name of
98
+ * the field being compared against.
99
+ */
100
+ SAME_AS: "same_as"
101
+ };
102
+ /**
103
+ * Build an `IssueItem`. TS uses the supplied `code` to pick the right
104
+ * `data` requirement at the call site — passing `MIN_LENGTH` without
105
+ * `data: { min }` is a compile error; passing `STRONG_PASSWORD` with
106
+ * `data: { pointsPerUnique: 5 }` is a compile error.
107
+ *
108
+ * `code` may be omitted (defaults to `IssueCode.VALUE_INVALID` — bare,
109
+ * no data).
110
+ *
111
+ * ```ts
112
+ * defineIssueItem({
113
+ * code: IssueCode.MIN_LENGTH,
114
+ * path: ['name'],
115
+ * message: 'Must be at least 3 characters',
116
+ * data: { min: 3 },
117
+ * });
118
+ * ```
119
+ */
120
+ function defineIssueItem(data) {
121
+ return {
122
+ type: "item",
123
+ ...data,
124
+ code: data.code || IssueCode.VALUE_INVALID
125
+ };
126
+ }
127
+ //#endregion
128
+ export { IssueCode, defineIssueItem };
129
+
130
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../../node_modules/@ebec/core/dist/index.mjs"],"sourcesContent":["//#region src/helpers/object.ts\nfunction isObject(item) {\n\treturn !!item && typeof item === \"object\" && !Array.isArray(item);\n}\n//#endregion\n//#region src/helpers/error.ts\nfunction isError(input) {\n\tif (!isObject(input)) return false;\n\tif (input instanceof Error) return true;\n\treturn typeof input.message === \"string\" && (typeof input.name === \"string\" || typeof input.stack === \"string\");\n}\n//#endregion\n//#region src/helpers/instanceof.ts\n/**\n* Property name used to store the cross-realm class-marker chain on instances.\n*\n* The chain is a `symbol[]` of `Symbol.for(...)` markers — one per class in the\n* inheritance path. Stored as a non-enumerable, non-writable, non-configurable\n* property so it stays out of `Object.keys()` and plain `JSON.stringify()`\n* output. `BaseError.toJSON()` re-emits it under the same key as a string\n* list (see {@link serializeInstanceofChain}), so on objects rehydrated from\n* that JSON the property holds a `string[]` instead.\n*\n* A well-formed chain always begins with `BASE_ERROR_INSTANCE` — every real\n* ebec error is a `BaseError` first, and subclass markers are appended on\n* top of it. Hand-built cross-realm stand-ins that carry a subclass marker\n* without it can invert that hierarchy (e.g. matching `@ebec/http`'s\n* `isHTTPError` while failing `@ebec/core`'s `isBaseError`).\n*/\nconst INSTANCEOF_PROPERTY = \"@instanceof\";\n/**\n* Append a class-marker symbol to the receiver's `@instanceof` chain.\n*\n* Each error class declares a `Symbol.for(...)` marker for itself and calls\n* `markInstanceof(this, MY_MARKER)` from its constructor. Subclass instances\n* accumulate markers from every ancestor in the chain, so a parent-class\n* guard can fast-path-match a subclass instance.\n*\n* Idempotent — re-marking the same instance with the same symbol is a no-op.\n*/\nfunction markInstanceof(target, marker) {\n\tconst existing = target[INSTANCEOF_PROPERTY];\n\tif (Array.isArray(existing)) {\n\t\tif (!existing.includes(marker)) existing.push(marker);\n\t\treturn;\n\t}\n\tObject.defineProperty(target, INSTANCEOF_PROPERTY, {\n\t\tvalue: [marker],\n\t\twritable: false,\n\t\tenumerable: false,\n\t\tconfigurable: false\n\t});\n}\n/**\n* Check whether the input's `@instanceof` chain carries `marker`.\n*\n* Returns `false` for non-objects, objects without the chain, or chains\n* stored as a non-array value (defensive).\n*\n* `strict` controls which chain entries count as a match. By default\n* (`strict: true`) only the native `Symbol.for(...)` form matches, which is\n* what an in-process instance carries. Pass `strict: false` to also match\n* the marker's `description` string: symbols are dropped by\n* `JSON.stringify`, so an error rehydrated from the JSON emitted by\n* `BaseError.toJSON()` carries the marker's description string in its chain\n* instead of the symbol, and only the loose form still recognizes it.\n* {@link matchesInstanceof} is `hasInstanceof(input, marker, false)`.\n*/\nfunction hasInstanceof(input, marker, strict = true) {\n\tif (!isObject(input)) return false;\n\tconst chain = input[INSTANCEOF_PROPERTY];\n\tif (!Array.isArray(chain)) return false;\n\tif (chain.includes(marker)) return true;\n\tif (strict) return false;\n\treturn typeof marker.description === \"string\" && chain.includes(marker.description);\n}\n/**\n* Serialize the input's `@instanceof` class-marker chain to its string form.\n*\n* Symbols are dropped by `JSON.stringify`, so `BaseError.toJSON()` emits the\n* chain as the markers' description strings instead. For `Symbol.for(...)`\n* markers the description *is* the registry key, so the string form carries\n* the same identity information as the symbol form.\n*\n* String entries pass through unchanged (a rehydrated chain re-serializes\n* losslessly); anything else is dropped. Each value is emitted once — a\n* re-marked rehydrated chain can hold the same marker in both its string\n* and symbol form.\n*/\nfunction serializeInstanceofChain(input) {\n\tif (!isObject(input)) return [];\n\tconst chain = input[INSTANCEOF_PROPERTY];\n\tif (!Array.isArray(chain)) return [];\n\tconst output = [];\n\tfor (const entry of chain) {\n\t\tlet value;\n\t\tif (typeof entry === \"symbol\") {\n\t\t\tif (entry.description) value = entry.description;\n\t\t} else if (typeof entry === \"string\") value = entry;\n\t\tif (typeof value === \"string\" && !output.includes(value)) output.push(value);\n\t}\n\treturn output;\n}\n/**\n* Check whether the input's `@instanceof` chain carries `marker` — either as\n* the native registry symbol (an in-process instance) or as the symbol's\n* description string (an error rehydrated from the JSON emitted by\n* `BaseError.toJSON()`).\n*\n* Prefer this over the strict (default) form of {@link hasInstanceof} as the\n* fast path of duck-type guards. Guards have no shape-based fallback, so the\n* strict form is the only check one performs: it matches only the symbol\n* form, so a guard built on it returns `false` outright for a\n* JSON-rehydrated subclass error — there is no slower path to fall back to.\n* Equivalent to `hasInstanceof(input, marker, false)`.\n*/\nfunction matchesInstanceof(input, marker) {\n\treturn hasInstanceof(input, marker, false);\n}\n//#endregion\n//#region src/helpers/check.ts\nconst BASE_ERROR_INSTANCE$1 = Symbol.for(\"@ebec/core/BaseError\");\nfunction isBaseError(input) {\n\treturn matchesInstanceof(input, BASE_ERROR_INSTANCE$1);\n}\nfunction isBaseErrorGroup(input) {\n\tif (!isBaseError(input)) return false;\n\tconst { errors } = input;\n\treturn Array.isArray(errors) && errors.length > 0 && errors.every((e) => isError(e));\n}\n//#endregion\n//#region src/helpers/error-code.ts\nfunction isErrorWithCode(error, code) {\n\tif (!isBaseError(error)) return false;\n\tif (Array.isArray(code)) return code.includes(error.code);\n\treturn error.code === code;\n}\n//#endregion\n//#region src/helpers/interpolate.ts\n/**\n* Substitute `{name}` placeholders in `str` with values from `data`.\n*\n* Placeholders whose key is missing from `data` (or explicitly\n* `undefined`) are left in the string verbatim, so a partially-populated\n* `data` degrades to a readable template rather than to `\"undefined\"`.\n*\n* - `regex` must carry the `g` flag — `String.prototype.matchAll` throws\n* without it.\n* - Substitution goes through `String.prototype.replace` with a string\n* replacement, so `$&`, `` $` ``, `$'` and `$1` inside a *substituted\n* value* are interpreted as replacement patterns rather than literals.\n* Treat `data` values as trusted, or escape `$` before passing them.\n*/\nfunction interpolate(str, data, regex = /\\{(\\w+)\\}/g) {\n\treturn Array.from(str.matchAll(regex)).reduce((acc, match) => {\n\t\tconst key = match[1];\n\t\tif (key && typeof data[key] !== \"undefined\") return acc.replace(match[0], String(data[key]));\n\t\treturn acc;\n\t}, str);\n}\n//#endregion\n//#region src/helpers/sanitize-code.ts\n/**\n* Convert a PascalCase class name to CONSTANT_CASE error code.\n* e.g. \"NotFoundError\" -> \"NOT_FOUND_ERROR\"\n*/\nfunction sanitizeErrorCode(input) {\n\treturn input.replace(/([a-z])([A-Z])/g, \"$1_$2\").replace(/([A-Z]+)([A-Z][a-z])/g, \"$1_$2\").toUpperCase();\n}\n//#endregion\n//#region src/helpers/serialize.ts\nfunction toSerializable(input) {\n\tif (isObject(input) && typeof input.toJSON === \"function\") return input.toJSON();\n\tif (isError(input)) return { message: input.message };\n\treturn input;\n}\n//#endregion\n//#region src/options/module.ts\nfunction isErrorOptions(input) {\n\tif (!isObject(input)) return false;\n\tif (typeof input.message !== \"undefined\" && typeof input.message !== \"string\") return false;\n\tif (typeof input.stack !== \"undefined\" && typeof input.stack !== \"string\") return false;\n\treturn typeof input.code === \"undefined\" || typeof input.code === \"string\";\n}\nfunction extractErrorOptions(input = {}) {\n\tif (typeof input === \"string\") return { message: input };\n\treturn input;\n}\n//#endregion\n//#region src/module.ts\nconst BASE_ERROR_INSTANCE = Symbol.for(\"@ebec/core/BaseError\");\nvar BaseError = class extends Error {\n\t/**\n\t* A unique identifier for the error.\n\t*/\n\tcode;\n\t/**\n\t* Represents the underlying cause or source of the error.\n\t*/\n\tcause;\n\t/**\n\t* A collection of errors for batch/group error scenarios.\n\t*/\n\terrors;\n\t/**\n\t* Structured validation failures, as an issue tree.\n\t* Always an array — empty when the error carries none.\n\t*/\n\tissues;\n\tconstructor(input = {}) {\n\t\tconst options = extractErrorOptions(input);\n\t\tlet message = options.message || \"An error occurred\";\n\t\tif (options.messageData) message = interpolate(message, options.messageData);\n\t\tsuper(message);\n\t\tif (options.cause !== void 0) this.cause = options.cause;\n\t\tif (typeof this.name === \"undefined\" || this.name === \"Error\") Object.defineProperty(this, \"name\", {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: this.constructor.name,\n\t\t\twritable: true\n\t\t});\n\t\tif (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);\n\t\tif (options.stack) this.stack = options.stack;\n\t\tthis.code = options.code || sanitizeErrorCode(this.constructor.name);\n\t\tif (options.errors !== void 0) this.errors = [...options.errors];\n\t\tthis.issues = Array.isArray(options.issues) ? [...options.issues] : [];\n\t\tmarkInstanceof(this, BASE_ERROR_INSTANCE);\n\t}\n\t/**\n\t* The class-marker chain rides along as a string list so the ancestor\n\t* information survives a JSON round-trip (symbols don't serialize) —\n\t* duck-type guards match rehydrated subclass errors through it via\n\t* `matchesInstanceof`.\n\t*/\n\ttoJSON() {\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tmessage: this.message,\n\t\t\tcode: this.code,\n\t\t\t...this.cause !== void 0 && { cause: toSerializable(this.cause) },\n\t\t\t...this.errors !== void 0 && { errors: this.errors.map((e) => toSerializable(e)) },\n\t\t\t...this.issues.length > 0 && { issues: [...this.issues] },\n\t\t\t[INSTANCEOF_PROPERTY]: serializeInstanceofChain(this)\n\t\t};\n\t}\n};\n//#endregion\n//#region src/catalog.ts\nfunction defineErrorCatalog(definitions) {\n\tconst catalog = {};\n\tfor (const key of Object.keys(definitions)) {\n\t\tconst entry = definitions[key];\n\t\tcatalog[key] = ((messageData, overrides = {}) => new BaseError({\n\t\t\t...entry,\n\t\t\t...overrides,\n\t\t\tcode: overrides.code ?? entry.code ?? key,\n\t\t\tmessage: overrides.message ?? entry.message,\n\t\t\tmessageData: overrides.messageData ?? messageData\n\t\t}));\n\t}\n\treturn catalog;\n}\n//#endregion\n//#region src/issue/check.ts\nfunction isObject$1(input) {\n\treturn !!input && typeof input === \"object\" && !Array.isArray(input);\n}\nfunction isIssuePath(input) {\n\tif (!Array.isArray(input)) return false;\n\treturn input.every((el) => typeof el === \"string\" || typeof el === \"number\" || typeof el === \"symbol\");\n}\nfunction isBaseIssue(input) {\n\tif (!isObject$1(input)) return false;\n\tif (typeof input.message !== \"string\") return false;\n\tif (!isIssuePath(input.path)) return false;\n\treturn typeof input.meta === \"undefined\" || isObject$1(input.meta);\n}\n/**\n* Structural check for a leaf node.\n*\n* Deliberately duck-typed rather than `instanceof`-based: issues cross\n* package and realm boundaries, so a tree assembled from two libraries —\n* or from two copies of this package — must still validate.\n*/\nfunction isIssueItem(input) {\n\tif (!isBaseIssue(input)) return false;\n\tif (input.type !== \"item\") return false;\n\treturn typeof input.code === \"string\";\n}\n/**\n* Structural check for a node with children. Recurses, so a group only\n* passes when every descendant is itself well-formed.\n*/\nfunction isIssueGroup(input) {\n\tif (!isBaseIssue(input)) return false;\n\tif (input.type !== \"group\") return false;\n\treturn Array.isArray(input.issues) && input.issues.every((issue) => isIssueItem(issue) || isIssueGroup(issue));\n}\n/**\n* Structural check for any node of the tree.\n*/\nfunction isIssue(input) {\n\treturn isIssueGroup(input) || isIssueItem(input);\n}\n//#endregion\n//#region src/issue/constants.ts\n/**\n* Vocabulary of well-known issue codes. Validators map their own failure\n* kinds onto these so consumer-side translation catalogs can ship one\n* localized message per code instead of falling back to a generic\n* \"invalid value\".\n*\n* Tracks the common ground between vuelidate, zod, joi, yup and\n* validator.js. The list lifts from vuelidate's catalog (snake_cased);\n* modern format codes (`PATTERN`, `UUID`, `DATE`, `JSON`, `BASE64`,\n* `STRONG_PASSWORD`, …) cover ground vuelidate predates. Every format\n* code names the format positively (`UUID`, `EMAIL`, `URL`, …) rather\n* than the failure mode (`NOT_UUID`, `INVALID_EMAIL`) so the registry\n* reads consistently.\n*\n* **This vocabulary is a default, not a requirement.** `IssueItem.code`\n* is widened to `IssueCode | (string & {})`, so a library with its own\n* vocabulary — `rapiq`'s `key_not_allowed`, an app's `email_taken` —\n* emits well-formed issues without touching this const at all. If you\n* want a typed const for your own codes, define one alongside this one:\n*\n* ```ts\n* import { IssueCode } from '@ebec/core';\n*\n* export const AppCode = {\n* ...IssueCode,\n* EMAIL_TAKEN: 'email_taken',\n* } as const;\n* ```\n*\n* Each entry's JSDoc documents the structured `data` producers should\n* attach when constructing the issue — templates can rely on those\n* placeholders being present (`{min}`, `{max}`, `{other}`, etc.).\n*/\nconst IssueCode = {\n\t/** Generic fallback when no more-specific code applies. `data`: — */\n\tVALUE_INVALID: \"value_invalid\",\n\t/** Every branch of a `oneOf` alternative failed. `data`: — */\n\tONE_OF_FAILED: \"one_of_failed\",\n\t/** Value is missing, `undefined`, `null`, or empty per the validator's semantics. `data`: — */\n\tREQUIRED: \"required\",\n\t/** Value contains characters outside the alphabetical set. `data`: — */\n\tALPHA: \"alpha\",\n\t/** Value contains characters outside the alphanumeric set. `data`: — */\n\tALPHA_NUM: \"alpha_num\",\n\t/** Value is not a number. `data`: — */\n\tNUMERIC: \"numeric\",\n\t/** Value is not an integer. `data`: — */\n\tINTEGER: \"integer\",\n\t/** Value is not a decimal number. `data`: — */\n\tDECIMAL: \"decimal\",\n\t/** Value is shorter than the configured minimum. `data`: `{ min: number }` */\n\tMIN_LENGTH: \"min_length\",\n\t/** Value is longer than the configured maximum. `data`: `{ max: number }` */\n\tMAX_LENGTH: \"max_length\",\n\t/** Numeric value is below the configured minimum. `data`: `{ min: number }` */\n\tMIN_VALUE: \"min_value\",\n\t/** Numeric value is above the configured maximum. `data`: `{ max: number }` */\n\tMAX_VALUE: \"max_value\",\n\t/** Numeric value falls outside the configured `[min, max]` range. `data`: `{ min: number, max: number }` */\n\tBETWEEN: \"between\",\n\t/** Value is not a valid email address. `data`: — */\n\tEMAIL: \"email\",\n\t/** Value is not a valid URL. `data`: — */\n\tURL: \"url\",\n\t/** Value is not a valid IP address. `data`: — */\n\tIP_ADDRESS: \"ip_address\",\n\t/** Value is not a valid MAC address. `data`: — */\n\tMAC_ADDRESS: \"mac_address\",\n\t/** Value is not a valid UUID. `data`: — */\n\tUUID: \"uuid\",\n\t/** Value is not a valid date / cannot be parsed as a date. `data`: — */\n\tDATE: \"date\",\n\t/**\n\t* Value does not match the expected regex pattern. `data`:\n\t* `{ pattern: string }` — source of the regex without flags so\n\t* catalogs can quote it in human-readable form.\n\t*/\n\tPATTERN: \"pattern\",\n\t/** Value is not valid JSON. `data`: — */\n\tJSON: \"json\",\n\t/** Value is not valid base64. `data`: — */\n\tBASE64: \"base64\",\n\t/**\n\t* Value does not meet the configured strong-password rules. `data`:\n\t* `{ minLength?: number, minLowercase?: number, minUppercase?: number,\n\t* minNumbers?: number, minSymbols?: number }` — only the keys the\n\t* producer chose to surface; missing keys mean \"the default for that\n\t* setting wasn't configured.\"\n\t*/\n\tSTRONG_PASSWORD: \"strong_password\",\n\t/**\n\t* Value must equal another named field's value (sibling-field assertion,\n\t* e.g. password-confirm). `data`: `{ other: string }` — the name of\n\t* the field being compared against.\n\t*/\n\tSAME_AS: \"same_as\"\n};\n//#endregion\n//#region src/issue/define.ts\n/**\n* Build an `IssueItem`. TS uses the supplied `code` to pick the right\n* `data` requirement at the call site — passing `MIN_LENGTH` without\n* `data: { min }` is a compile error; passing `STRONG_PASSWORD` with\n* `data: { pointsPerUnique: 5 }` is a compile error.\n*\n* `code` may be omitted (defaults to `IssueCode.VALUE_INVALID` — bare,\n* no data).\n*\n* ```ts\n* defineIssueItem({\n* code: IssueCode.MIN_LENGTH,\n* path: ['name'],\n* message: 'Must be at least 3 characters',\n* data: { min: 3 },\n* });\n* ```\n*/\nfunction defineIssueItem(data) {\n\treturn {\n\t\ttype: \"item\",\n\t\t...data,\n\t\tcode: data.code || IssueCode.VALUE_INVALID\n\t};\n}\n/**\n* Build an {@link IssueGroup} — a node that carries child issues.\n*\n* The children's `path` values are used as given; this factory does not\n* rewrite them. When the children came from validating a *sub*-structure,\n* rebase them with {@link prefixIssuePath} first so the tree keeps its\n* absolute-path invariant.\n*/\nfunction defineIssueGroup(data) {\n\treturn {\n\t\ttype: \"group\",\n\t\t...data\n\t};\n}\n//#endregion\n//#region src/issue/flatten.ts\n/**\n* Collect every leaf of the tree, in pre-order, discarding grouping.\n*\n* This is the workhorse for consumers that render per-field errors: since\n* every node carries an absolute `path` (see `IssueBase.path`), the result\n* can be indexed by field directly, with no tree walk to reassemble\n* prefixes.\n*\n* Returned items are the **same object references** held by the tree, not\n* copies — cheap to call, but do not mutate what you get back.\n*/\nfunction flattenIssueItems(issues) {\n\tconst output = [];\n\tfor (const issue of issues) if (isIssueItem(issue)) output.push(issue);\n\telse output.push(...flattenIssueItems(issue.issues));\n\treturn output;\n}\n/**\n* Collect every group of the tree, in pre-order, including nested groups.\n*\n* A group is emitted before its own descendants are visited, so the result\n* reads outermost-first. As with {@link flattenIssueItems}, entries are\n* live references into the tree.\n*/\nfunction flattenIssueGroups(issues) {\n\tconst output = [];\n\tfor (const issue of issues) if (isIssueGroup(issue)) {\n\t\toutput.push(issue);\n\t\toutput.push(...flattenIssueGroups(issue.issues));\n\t}\n\treturn output;\n}\n//#endregion\n//#region src/issue/format.ts\n/**\n* Render an issue's user-facing message.\n*\n* Resolution order:\n* 1. If `templates[code]` exists, return `interpolate(template, issue.data)`.\n* 2. Else return `issue.message` (the default English rendering set at\n* construction time).\n* 3. Else return `fallback`.\n*\n* The eager `message` written at construction time is what makes step 2\n* useful: a consumer with no catalog at all still gets something readable,\n* and a consumer with a partial catalog falls back per-code rather than\n* all-or-nothing.\n*/\nfunction formatIssue(issue, templates, fallback = \"\") {\n\tif (templates && issue.code) {\n\t\tconst template = templates[issue.code];\n\t\tif (typeof template === \"string\") return interpolate(template, issue.data || {});\n\t}\n\tif (typeof issue.message === \"string\" && issue.message.length > 0) return issue.message;\n\treturn fallback;\n}\n//#endregion\n//#region src/issue/prefix.ts\n/**\n* Rebase an issue onto a parent path, recursing into groups so every\n* descendant is rebased too.\n*\n* This is the step that maintains the absolute-path invariant (see\n* `IssueBase.path`). Whenever a producer validates a *sub*-structure and\n* merges the resulting issues into a larger tree, the children arrive with\n* paths relative to that sub-structure and have to be rewritten. Doing it\n* only at the top level is the tempting bug: a child that already wrapped\n* its own failures in an {@link IssueGroup} would surface inner leaves\n* missing the parent segment, and every consumer relying on\n* {@link flattenIssueItems} for per-field lookup would silently mis-index\n* exactly the nested cases.\n*\n* ```ts\n* // validating `address` produced issues at ['street']\n* const rebased = issues.map((issue) => prefixIssuePath(issue, ['address']));\n* // → paths are now ['address', 'street'], at every depth\n* ```\n*\n* **Returns copies.** The input is never mutated: each visited node is\n* shallow-copied and a group's `issues` array is rebuilt from the rebased\n* children, so the whole spine is fresh. `data` and `meta` are carried over\n* by reference — cheap, but it means a caller that mutates `meta` on the\n* result also mutates it on the original. Copying happens unconditionally,\n* including for an empty `prefix`.\n*/\nfunction prefixIssuePath(issue, prefix) {\n\tconst prefixed = {\n\t\t...issue,\n\t\tpath: [...prefix, ...issue.path || []]\n\t};\n\tif (prefixed.type === \"group\") prefixed.issues = prefixed.issues.map((nested) => prefixIssuePath(nested, prefix));\n\treturn prefixed;\n}\n//#endregion\nexport { BASE_ERROR_INSTANCE, BaseError, INSTANCEOF_PROPERTY, IssueCode, defineErrorCatalog, defineIssueGroup, defineIssueItem, extractErrorOptions, flattenIssueGroups, flattenIssueItems, formatIssue, hasInstanceof, interpolate, isBaseError, isBaseErrorGroup, isError, isErrorOptions, isErrorWithCode, isIssue, isIssueGroup, isIssueItem, isObject, markInstanceof, matchesInstanceof, prefixIssuePath, sanitizeErrorCode, serializeInstanceofChain, toSerializable };\n\n//# sourceMappingURL=index.mjs.map"],"x_google_ignoreList":[0],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmVA,MAAM,YAAY;;CAEjB,eAAe;;CAEf,eAAe;;CAEf,UAAU;;CAEV,OAAO;;CAEP,WAAW;;CAEX,SAAS;;CAET,SAAS;;CAET,SAAS;;CAET,YAAY;;CAEZ,YAAY;;CAEZ,WAAW;;CAEX,WAAW;;CAEX,SAAS;;CAET,OAAO;;CAEP,KAAK;;CAEL,YAAY;;CAEZ,aAAa;;CAEb,MAAM;;CAEN,MAAM;;;;;;CAMN,SAAS;;CAET,MAAM;;CAEN,QAAQ;;;;;;;;CAQR,iBAAiB;;;;;;CAMjB,SAAS;AACV;;;;;;;;;;;;;;;;;;;AAqBA,SAAS,gBAAgB,MAAM;CAC9B,OAAO;EACN,MAAM;EACN,GAAG;EACH,MAAM,KAAK,QAAQ,UAAU;CAC9B;AACD"}
package/dist/swagger.json CHANGED
@@ -428,6 +428,19 @@
428
428
  }
429
429
  ]
430
430
  },
431
+ "caseSensitive": {
432
+ "anyOf": [
433
+ {
434
+ "type": "array",
435
+ "items": {
436
+ "type": "string"
437
+ }
438
+ },
439
+ {
440
+ "type": "null"
441
+ }
442
+ ]
443
+ },
431
444
  "allowed": {
432
445
  "anyOf": [
433
446
  {
@@ -444,6 +457,7 @@
444
457
  },
445
458
  "required": [
446
459
  "indexed",
460
+ "caseSensitive",
447
461
  "allowed"
448
462
  ],
449
463
  "type": "object",
@@ -3696,6 +3710,34 @@
3696
3710
  ],
3697
3711
  "type": "object"
3698
3712
  },
3713
+ "EntityRecordResponseIdentityProviderAccount": {
3714
+ "properties": {
3715
+ "meta": {
3716
+ "$ref": "#/components/schemas/EntityRecordMeta"
3717
+ },
3718
+ "data": {
3719
+ "$ref": "#/components/schemas/IdentityProviderAccount"
3720
+ }
3721
+ },
3722
+ "required": [
3723
+ "meta",
3724
+ "data"
3725
+ ],
3726
+ "type": "object",
3727
+ "description": "The wire shape of every entity-record response: the record under\n`data`, response-scoped extras under `meta` (mirroring\n`EntityCollectionResponse`)."
3728
+ },
3729
+ "IdentityProviderLinkConfirmPayload": {
3730
+ "properties": {
3731
+ "handle": {
3732
+ "type": "string"
3733
+ }
3734
+ },
3735
+ "required": [
3736
+ "handle"
3737
+ ],
3738
+ "type": "object",
3739
+ "description": "Body of `POST /identity-providers/:id/link-confirm` (issue #3439): the\none-time handle the callback returned on the account console URL. The\naccount row is written for the AUTHENTICATED caller, so the handle names\na pending link rather than authorizing one on its own."
3740
+ },
3699
3741
  "EntityCollectionResponseIdentityProviderAccount": {
3700
3742
  "properties": {
3701
3743
  "meta": {
@@ -3734,22 +3776,6 @@
3734
3776
  ],
3735
3777
  "type": "object"
3736
3778
  },
3737
- "EntityRecordResponseIdentityProviderAccount": {
3738
- "properties": {
3739
- "meta": {
3740
- "$ref": "#/components/schemas/EntityRecordMeta"
3741
- },
3742
- "data": {
3743
- "$ref": "#/components/schemas/IdentityProviderAccount"
3744
- }
3745
- },
3746
- "required": [
3747
- "meta",
3748
- "data"
3749
- ],
3750
- "type": "object",
3751
- "description": "The wire shape of every entity-record response: the record under\n`data`, response-scoped extras under `meta` (mirroring\n`EntityCollectionResponse`)."
3752
- },
3753
3779
  "IdentityProviderRoleMapping": {
3754
3780
  "properties": {
3755
3781
  "name": {
@@ -9655,7 +9681,14 @@
9655
9681
  "content": {
9656
9682
  "application/json": {
9657
9683
  "schema": {
9658
- "$ref": "#/components/schemas/Response"
9684
+ "anyOf": [
9685
+ {
9686
+ "type": "string"
9687
+ },
9688
+ {
9689
+ "$ref": "#/components/schemas/Response"
9690
+ }
9691
+ ]
9659
9692
  }
9660
9693
  }
9661
9694
  }
@@ -9688,7 +9721,14 @@
9688
9721
  "content": {
9689
9722
  "application/json": {
9690
9723
  "schema": {
9691
- "$ref": "#/components/schemas/Response"
9724
+ "anyOf": [
9725
+ {
9726
+ "type": "string"
9727
+ },
9728
+ {
9729
+ "$ref": "#/components/schemas/Response"
9730
+ }
9731
+ ]
9692
9732
  }
9693
9733
  }
9694
9734
  }
@@ -9712,6 +9752,94 @@
9712
9752
  ]
9713
9753
  }
9714
9754
  },
9755
+ "/identity-providers/{id}/link-confirm": {
9756
+ "post": {
9757
+ "operationId": "ConfirmLink",
9758
+ "responses": {
9759
+ "200": {
9760
+ "description": "Ok",
9761
+ "content": {
9762
+ "application/json": {
9763
+ "schema": {
9764
+ "$ref": "#/components/schemas/EntityRecordResponseIdentityProviderAccount"
9765
+ }
9766
+ }
9767
+ }
9768
+ }
9769
+ },
9770
+ "description": "The bearer-authenticated half of the link (issue #3439): the account\nrow is written here, for the AUTHENTICATED user, never in the callback.",
9771
+ "tags": [],
9772
+ "parameters": [
9773
+ {
9774
+ "allowEmptyValue": false,
9775
+ "deprecated": false,
9776
+ "description": "",
9777
+ "in": "path",
9778
+ "name": "id",
9779
+ "required": true,
9780
+ "schema": {
9781
+ "type": "string"
9782
+ },
9783
+ "examples": {}
9784
+ }
9785
+ ],
9786
+ "requestBody": {
9787
+ "description": "",
9788
+ "required": true,
9789
+ "content": {
9790
+ "application/json": {
9791
+ "schema": {
9792
+ "$ref": "#/components/schemas/IdentityProviderLinkConfirmPayload"
9793
+ }
9794
+ }
9795
+ }
9796
+ }
9797
+ }
9798
+ },
9799
+ "/realms/{realmId}/identity-providers/{id}/link-confirm": {
9800
+ "post": {
9801
+ "operationId": "ConfirmLink_2",
9802
+ "responses": {
9803
+ "200": {
9804
+ "description": "Ok",
9805
+ "content": {
9806
+ "application/json": {
9807
+ "schema": {
9808
+ "$ref": "#/components/schemas/EntityRecordResponseIdentityProviderAccount"
9809
+ }
9810
+ }
9811
+ }
9812
+ }
9813
+ },
9814
+ "description": "The bearer-authenticated half of the link (issue #3439): the account\nrow is written here, for the AUTHENTICATED user, never in the callback.",
9815
+ "tags": [],
9816
+ "parameters": [
9817
+ {
9818
+ "allowEmptyValue": false,
9819
+ "deprecated": false,
9820
+ "description": "",
9821
+ "in": "path",
9822
+ "name": "id",
9823
+ "required": true,
9824
+ "schema": {
9825
+ "type": "string"
9826
+ },
9827
+ "examples": {}
9828
+ }
9829
+ ],
9830
+ "requestBody": {
9831
+ "description": "",
9832
+ "required": true,
9833
+ "content": {
9834
+ "application/json": {
9835
+ "schema": {
9836
+ "$ref": "#/components/schemas/IdentityProviderLinkConfirmPayload"
9837
+ }
9838
+ }
9839
+ }
9840
+ }
9841
+ }
9842
+ },
9715
9843
  "/identity-provider-accounts": {
9716
9844
  "get": {
9717
9845
  "operationId": "GetMany_10",
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,WAAW,EAKd,MAAM,gBAAgB,CAAC;AAQxB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAgGzD;AA0ED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CA8BvE"}
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,WAAW,EAKd,MAAM,gBAAgB,CAAC;AAQxB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CA8FzD;AA0ED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CA8BvE"}
@@ -5,9 +5,9 @@ import { hasOwnProperty, isObject } from "@authup/kit";
5
5
  import { AuthupError, ErrorCode, codeFromHttpStatus, isAuthupError, normalizeError } from "@authup/errors";
6
6
  import { CodecError, ParseError } from "@rapiq/core";
7
7
  import { buildErrorMessageForAttributes, isValidupError, stringifyPath } from "validup";
8
- import { EntityRelationLookupError } from "typeorm-extension";
9
- import { isClientError } from "hapic";
10
8
  import { isHTTPError } from "@ebec/http";
9
+ import { isClientError } from "hapic";
10
+ import { EntityRelationLookupError } from "typeorm-extension";
11
11
  //#region src/utils/error.ts
12
12
  /**
13
13
  * Normalize an unknown error to an AuthupError. Recognised shapes:
@@ -32,13 +32,12 @@ import { isHTTPError } from "@ebec/http";
32
32
  });
33
33
  if (isValidupError(input)) {
34
34
  const paths = input.issues.map((issue) => stringifyPath(issue.path));
35
- const error = new AuthupError({
35
+ return new AuthupError({
36
36
  code: ErrorCode.BAD_REQUEST,
37
37
  stack: input.stack,
38
- message: input.message || buildErrorMessageForAttributes(paths)
38
+ message: input.message || buildErrorMessageForAttributes(paths),
39
+ issues: input.issues
39
40
  });
40
- error.issues.push(...input.issues);
41
- return error;
42
41
  }
43
42
  if (input instanceof ParseError || input instanceof CodecError) return new AuthupError({
44
43
  code: ErrorCode.BAD_REQUEST,
@@ -1 +1 @@
1
- {"version":3,"file":"error.mjs","names":["AuthupError","ErrorCode","codeFromHttpStatus","isAuthupError","normalizeError","isHTTPError","isClientError","CodecError","ParseError","EntityRelationLookupError","buildErrorMessageForAttributes","isValidupError","stringifyPath","hasOwnProperty","isObject","sanitizeError","input","code","ENTITY_RELATION_INVALID","message","stack","paths","issues","map","issue","path","error","BAD_REQUEST","push","UPSTREAM_ERROR","status","undefined","ENTITY_CONFLICT","STORAGE_INSUFFICIENT","INTERNAL_ERROR","DESCRIBE_BODY_MAX_LENGTH","DESCRIBE_CAUSE_MAX_DEPTH","DESCRIBE_CAUSE_KEYS","describeBody","value","JSON","stringify","String","Object","prototype","toString","call","length","substring","describeCauseLink","name","parts","details","key","join","describeCauseChain","links","seen","Set","current","cause","has","add","describeError","headline","lines","response","body","data","causes"],"sources":["../../src/utils/error.ts"],"sourcesContent":["/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n AuthupError,\n ErrorCode,\n codeFromHttpStatus,\n isAuthupError,\n normalizeError,\n} from '@authup/errors';\nimport { isHTTPError } from '@ebec/http';\nimport { isClientError } from 'hapic';\nimport { CodecError, ParseError } from '@rapiq/core';\nimport { EntityRelationLookupError } from 'typeorm-extension';\nimport { buildErrorMessageForAttributes, isValidupError, stringifyPath } from 'validup';\nimport { hasOwnProperty, isObject } from '@authup/kit';\n\n/**\n * Normalize an unknown error to an AuthupError. Recognised shapes:\n *\n * 1. AuthupError instance → returned as-is\n * 2. EntityRelationLookupError → BAD_REQUEST AuthupError\n * 3. validup Issue error → BAD_REQUEST AuthupError carrying issues\n * 4. rapiq ParseError / CodecError → BAD_REQUEST AuthupError (client wire query)\n * 5. hapic ClientError → UPSTREAM_ERROR AuthupError (outbound call)\n * 6. foreign @ebec/http HTTPError → AuthupError with the closest semantic code\n * 7. driver error w/ a recognised code → ENTITY_CONFLICT or STORAGE_INSUFFICIENT\n * 8. anything else → INTERNAL_ERROR AuthupError\n *\n * The HTTP-status concern is handled separately by `httpStatusFromCode` in\n * the adapter — this function only assigns a semantic `code`.\n */\nexport function sanitizeError(input: unknown): AuthupError {\n if (isAuthupError(input)) {\n return input;\n }\n\n if (input instanceof EntityRelationLookupError) {\n return new AuthupError({\n code: ErrorCode.ENTITY_RELATION_INVALID,\n message: input.message,\n stack: input.stack,\n });\n }\n\n if (isValidupError(input)) {\n const paths = input.issues.map((issue) => stringifyPath(issue.path));\n const error = new AuthupError({\n code: ErrorCode.BAD_REQUEST,\n stack: input.stack,\n message: input.message || buildErrorMessageForAttributes(paths),\n });\n\n error.issues.push(...input.issues);\n return error;\n }\n\n if (input instanceof ParseError || input instanceof CodecError) {\n return new AuthupError({\n code: ErrorCode.BAD_REQUEST,\n message: input.message,\n stack: input.stack,\n });\n }\n\n /**\n * An outbound call failed. This branch MUST precede the `isHTTPError`\n * one below: a hapic `HttpResponseError` extends `BaseError` and carries\n * the upstream `status`, so the duck guard matches it and would mirror\n * that status onto our own response. An upstream 400 would then read as\n * \"your request was malformed\" when the caller's request was fine.\n *\n * The message is deliberately dropped rather than forwarded: hapic\n * embeds the outbound method and URL in it (`400 Bad Request (POST\n * https://idp.example.com/token)`), which must not reach the caller.\n * `describeError` is what carries the detail, into the log only.\n */\n if (isClientError(input)) {\n return new AuthupError({\n code: ErrorCode.UPSTREAM_ERROR,\n message: 'A request to an upstream service failed.',\n stack: input.stack,\n });\n }\n\n if (isHTTPError(input)) {\n return new AuthupError({\n code: codeFromHttpStatus(input.status),\n message: input.message,\n stack: input.stack,\n });\n }\n\n if (isObject(input)) {\n const code = hasOwnProperty(input, 'code') &&\n typeof input.code === 'string' ?\n input.code :\n undefined;\n\n /**\n * @see https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html\n */\n switch (code) {\n case '23505':\n case 'ER_DUP_ENTRY':\n case 'SQLITE_CONSTRAINT_UNIQUE': {\n return new AuthupError({\n code: ErrorCode.ENTITY_CONFLICT,\n message: 'An entry with some unique attributes already exists.',\n stack: input.stack as string | undefined,\n });\n }\n case 'ER_DISK_FULL':\n return new AuthupError({\n code: ErrorCode.STORAGE_INSUFFICIENT,\n message: 'No database operation possible, due to the lack of free disk space.',\n stack: input.stack as string | undefined,\n });\n }\n\n return new AuthupError({\n code: ErrorCode.INTERNAL_ERROR,\n message: input.message as string | undefined,\n stack: input.stack as string | undefined,\n });\n }\n\n return new AuthupError({ code: ErrorCode.INTERNAL_ERROR });\n}\n\nconst DESCRIBE_BODY_MAX_LENGTH = 1024;\nconst DESCRIBE_CAUSE_MAX_DEPTH = 5;\n\n// Fields node attaches to a syscall error. Without them a transport failure\n// reads as a bare \"connect ECONNREFUSED\" with no way back to the reason.\nconst DESCRIBE_CAUSE_KEYS = ['code', 'errno', 'syscall', 'address', 'port'] as const;\n\nfunction describeBody(input: unknown): string | undefined {\n let value: string;\n\n if (typeof input === 'string') {\n value = input;\n } else {\n try {\n value = JSON.stringify(input) ?? String(input);\n } catch {\n // A body that cannot be serialized (circular, a stream) is\n // still worth naming by shape.\n value = Object.prototype.toString.call(input);\n }\n }\n\n if (value.length === 0) {\n return undefined;\n }\n\n if (value.length > DESCRIBE_BODY_MAX_LENGTH) {\n return `${value.substring(0, DESCRIBE_BODY_MAX_LENGTH)}… (truncated)`;\n }\n\n return value;\n}\n\nfunction describeCauseLink(input: object): string {\n const error = input as Error;\n const name = typeof error.name === 'string' ? error.name : 'Error';\n const parts: string[] = [`${name}: ${error.message}`];\n\n const details: string[] = [];\n for (const key of DESCRIBE_CAUSE_KEYS) {\n const value = (input as Record<string, unknown>)[key];\n if (typeof value === 'string' || typeof value === 'number') {\n details.push(`${key}=${value}`);\n }\n }\n\n if (details.length > 0) {\n parts.push(`(${details.join(' ')})`);\n }\n\n return parts.join(' ');\n}\n\nfunction describeCauseChain(input: unknown): string | undefined {\n const links: string[] = [];\n const seen = new Set<unknown>();\n\n let current: unknown = isObject(input) ? (input as { cause?: unknown }).cause : undefined;\n\n while (isObject(current) && !seen.has(current) && links.length < DESCRIBE_CAUSE_MAX_DEPTH) {\n seen.add(current);\n links.push(describeCauseLink(current));\n current = (current as { cause?: unknown }).cause;\n }\n\n if (links.length === 0) {\n return undefined;\n }\n\n return links.join(' <- ');\n}\n\n/**\n * Render an error for the LOG. It is the counterpart of `@authup/errors`'\n * `serializeError`, which renders one for the response.\n *\n * The detail an outbound failure carries never survives `sanitizeError`\n * (by design: upstream internals must not reach the caller), and\n * `Error.cause` is non-enumerable, so a plain serialization drops it too.\n * Both were therefore already gone by the time anything was written,\n * which left a refused connection and an upstream `invalid_request`\n * indistinguishable in the log.\n *\n * Everything not present is omitted, so an ordinary error still renders\n * as its bare message.\n */\nexport function describeError(input: unknown, headline?: string): string {\n const error = normalizeError(input);\n\n const lines: string[] = [];\n if (headline) {\n lines.push(headline);\n }\n lines.push(error.message);\n\n // hapic attaches the decoded body to the response through a getter, so\n // it is non-enumerable and only reachable by an explicit read.\n if (isClientError(error) && error.response) {\n lines.push(` upstream status: ${error.response.status}`);\n\n const body = describeBody(error.response.data);\n if (body) {\n lines.push(` upstream body: ${body}`);\n }\n }\n\n const causes = describeCauseChain(error);\n if (causes) {\n lines.push(` cause: ${causes}`);\n }\n\n if (error.stack) {\n lines.push(` stack: ${error.stack}`);\n }\n\n return lines.join('\\n');\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"error.mjs","names":["AuthupError","ErrorCode","codeFromHttpStatus","isAuthupError","normalizeError","isHTTPError","isClientError","CodecError","ParseError","EntityRelationLookupError","buildErrorMessageForAttributes","isValidupError","stringifyPath","hasOwnProperty","isObject","sanitizeError","input","code","ENTITY_RELATION_INVALID","message","stack","paths","issues","map","issue","path","BAD_REQUEST","UPSTREAM_ERROR","status","undefined","ENTITY_CONFLICT","STORAGE_INSUFFICIENT","INTERNAL_ERROR","DESCRIBE_BODY_MAX_LENGTH","DESCRIBE_CAUSE_MAX_DEPTH","DESCRIBE_CAUSE_KEYS","describeBody","value","JSON","stringify","String","Object","prototype","toString","call","length","substring","describeCauseLink","error","name","parts","details","key","push","join","describeCauseChain","links","seen","Set","current","cause","has","add","describeError","headline","lines","response","body","data","causes"],"sources":["../../src/utils/error.ts"],"sourcesContent":["/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n AuthupError,\n ErrorCode,\n codeFromHttpStatus,\n isAuthupError,\n normalizeError,\n} from '@authup/errors';\nimport { isHTTPError } from '@ebec/http';\nimport { isClientError } from 'hapic';\nimport { CodecError, ParseError } from '@rapiq/core';\nimport { EntityRelationLookupError } from 'typeorm-extension';\nimport { buildErrorMessageForAttributes, isValidupError, stringifyPath } from 'validup';\nimport { hasOwnProperty, isObject } from '@authup/kit';\n\n/**\n * Normalize an unknown error to an AuthupError. Recognised shapes:\n *\n * 1. AuthupError instance → returned as-is\n * 2. EntityRelationLookupError → BAD_REQUEST AuthupError\n * 3. validup Issue error → BAD_REQUEST AuthupError carrying issues\n * 4. rapiq ParseError / CodecError → BAD_REQUEST AuthupError (client wire query)\n * 5. hapic ClientError → UPSTREAM_ERROR AuthupError (outbound call)\n * 6. foreign @ebec/http HTTPError → AuthupError with the closest semantic code\n * 7. driver error w/ a recognised code → ENTITY_CONFLICT or STORAGE_INSUFFICIENT\n * 8. anything else → INTERNAL_ERROR AuthupError\n *\n * The HTTP-status concern is handled separately by `httpStatusFromCode` in\n * the adapter — this function only assigns a semantic `code`.\n */\nexport function sanitizeError(input: unknown): AuthupError {\n if (isAuthupError(input)) {\n return input;\n }\n\n if (input instanceof EntityRelationLookupError) {\n return new AuthupError({\n code: ErrorCode.ENTITY_RELATION_INVALID,\n message: input.message,\n stack: input.stack,\n });\n }\n\n if (isValidupError(input)) {\n const paths = input.issues.map((issue) => stringifyPath(issue.path));\n return new AuthupError({\n code: ErrorCode.BAD_REQUEST,\n stack: input.stack,\n message: input.message || buildErrorMessageForAttributes(paths),\n issues: input.issues,\n });\n }\n\n if (input instanceof ParseError || input instanceof CodecError) {\n return new AuthupError({\n code: ErrorCode.BAD_REQUEST,\n message: input.message,\n stack: input.stack,\n });\n }\n\n /**\n * An outbound call failed. This branch MUST precede the `isHTTPError`\n * one below: a hapic `HttpResponseError` extends `BaseError` and carries\n * the upstream `status`, so the duck guard matches it and would mirror\n * that status onto our own response. An upstream 400 would then read as\n * \"your request was malformed\" when the caller's request was fine.\n *\n * The message is deliberately dropped rather than forwarded: hapic\n * embeds the outbound method and URL in it (`400 Bad Request (POST\n * https://idp.example.com/token)`), which must not reach the caller.\n * `describeError` is what carries the detail, into the log only.\n */\n if (isClientError(input)) {\n return new AuthupError({\n code: ErrorCode.UPSTREAM_ERROR,\n message: 'A request to an upstream service failed.',\n stack: input.stack,\n });\n }\n\n if (isHTTPError(input)) {\n return new AuthupError({\n code: codeFromHttpStatus(input.status),\n message: input.message,\n stack: input.stack,\n });\n }\n\n if (isObject(input)) {\n const code = hasOwnProperty(input, 'code') &&\n typeof input.code === 'string' ?\n input.code :\n undefined;\n\n /**\n * @see https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html\n */\n switch (code) {\n case '23505':\n case 'ER_DUP_ENTRY':\n case 'SQLITE_CONSTRAINT_UNIQUE': {\n return new AuthupError({\n code: ErrorCode.ENTITY_CONFLICT,\n message: 'An entry with some unique attributes already exists.',\n stack: input.stack as string | undefined,\n });\n }\n case 'ER_DISK_FULL':\n return new AuthupError({\n code: ErrorCode.STORAGE_INSUFFICIENT,\n message: 'No database operation possible, due to the lack of free disk space.',\n stack: input.stack as string | undefined,\n });\n }\n\n return new AuthupError({\n code: ErrorCode.INTERNAL_ERROR,\n message: input.message as string | undefined,\n stack: input.stack as string | undefined,\n });\n }\n\n return new AuthupError({ code: ErrorCode.INTERNAL_ERROR });\n}\n\nconst DESCRIBE_BODY_MAX_LENGTH = 1024;\nconst DESCRIBE_CAUSE_MAX_DEPTH = 5;\n\n// Fields node attaches to a syscall error. Without them a transport failure\n// reads as a bare \"connect ECONNREFUSED\" with no way back to the reason.\nconst DESCRIBE_CAUSE_KEYS = ['code', 'errno', 'syscall', 'address', 'port'] as const;\n\nfunction describeBody(input: unknown): string | undefined {\n let value: string;\n\n if (typeof input === 'string') {\n value = input;\n } else {\n try {\n value = JSON.stringify(input) ?? String(input);\n } catch {\n // A body that cannot be serialized (circular, a stream) is\n // still worth naming by shape.\n value = Object.prototype.toString.call(input);\n }\n }\n\n if (value.length === 0) {\n return undefined;\n }\n\n if (value.length > DESCRIBE_BODY_MAX_LENGTH) {\n return `${value.substring(0, DESCRIBE_BODY_MAX_LENGTH)}… (truncated)`;\n }\n\n return value;\n}\n\nfunction describeCauseLink(input: object): string {\n const error = input as Error;\n const name = typeof error.name === 'string' ? error.name : 'Error';\n const parts: string[] = [`${name}: ${error.message}`];\n\n const details: string[] = [];\n for (const key of DESCRIBE_CAUSE_KEYS) {\n const value = (input as Record<string, unknown>)[key];\n if (typeof value === 'string' || typeof value === 'number') {\n details.push(`${key}=${value}`);\n }\n }\n\n if (details.length > 0) {\n parts.push(`(${details.join(' ')})`);\n }\n\n return parts.join(' ');\n}\n\nfunction describeCauseChain(input: unknown): string | undefined {\n const links: string[] = [];\n const seen = new Set<unknown>();\n\n let current: unknown = isObject(input) ? (input as { cause?: unknown }).cause : undefined;\n\n while (isObject(current) && !seen.has(current) && links.length < DESCRIBE_CAUSE_MAX_DEPTH) {\n seen.add(current);\n links.push(describeCauseLink(current));\n current = (current as { cause?: unknown }).cause;\n }\n\n if (links.length === 0) {\n return undefined;\n }\n\n return links.join(' <- ');\n}\n\n/**\n * Render an error for the LOG. It is the counterpart of `@authup/errors`'\n * `serializeError`, which renders one for the response.\n *\n * The detail an outbound failure carries never survives `sanitizeError`\n * (by design: upstream internals must not reach the caller), and\n * `Error.cause` is non-enumerable, so a plain serialization drops it too.\n * Both were therefore already gone by the time anything was written,\n * which left a refused connection and an upstream `invalid_request`\n * indistinguishable in the log.\n *\n * Everything not present is omitted, so an ordinary error still renders\n * as its bare message.\n */\nexport function describeError(input: unknown, headline?: string): string {\n const error = normalizeError(input);\n\n const lines: string[] = [];\n if (headline) {\n lines.push(headline);\n }\n lines.push(error.message);\n\n // hapic attaches the decoded body to the response through a getter, so\n // it is non-enumerable and only reachable by an explicit read.\n if (isClientError(error) && error.response) {\n lines.push(` upstream status: ${error.response.status}`);\n\n const body = describeBody(error.response.data);\n if (body) {\n lines.push(` upstream body: ${body}`);\n }\n }\n\n const causes = describeCauseChain(error);\n if (causes) {\n lines.push(` cause: ${causes}`);\n }\n\n if (error.stack) {\n lines.push(` stack: ${error.stack}`);\n }\n\n return lines.join('\\n');\n}\n"],"mappings":"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"}