@payez/next-mvp 4.8.1 → 4.8.3
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/POST-INSTALL.md +408 -408
- package/README.md +859 -859
- package/dist/api-handlers/admin/audit.js +13 -21
- package/dist/api-handlers/admin/sessions.js +59 -45
- package/dist/api-handlers/admin/stats.js +1 -1
- package/dist/api-handlers/admin/users.js +15 -23
- package/dist/api-handlers/admin/vibe-data.d.ts +5 -0
- package/dist/api-handlers/admin/vibe-data.js +5 -0
- package/dist/components/account/MobileNavDrawer.js +18 -18
- package/dist/components/account/UserAvatarMenu.js +1 -1
- package/dist/components/admin/AlertSettingsTab.js +40 -40
- package/dist/components/admin/LoggingSettingsTab.js +28 -28
- package/dist/lib/session-store.js +21 -21
- package/dist/lib/startup-init.js +19 -19
- package/dist/pages/login/page.js +28 -28
- package/dist/pages/settings/EnhancedSettingsPage.js +17 -17
- package/dist/vibe/client.d.ts +1 -1
- package/dist/vibe/client.js +2 -1
- package/dist/vibe/filters.d.ts +36 -0
- package/dist/vibe/filters.js +47 -0
- package/dist/vibe/generic.js +2 -1
- package/dist/vibe/sessions.js +28 -3
- package/package.json +2 -2
- package/scripts/check-publish-eol.mjs +33 -15
- package/src/api/auth-handler.ts +550 -550
- package/src/api/index.ts +17 -17
- package/src/api-handlers/account/change-password.ts +170 -170
- package/src/api-handlers/account/masked-info.ts +46 -46
- package/src/api-handlers/account/profile.ts +99 -99
- package/src/api-handlers/account/recovery/forward.ts +117 -117
- package/src/api-handlers/account/recovery/initiate.ts +59 -59
- package/src/api-handlers/account/recovery/send-code.ts +21 -21
- package/src/api-handlers/account/recovery/verify-code.ts +20 -20
- package/src/api-handlers/account/reset-password.ts +87 -87
- package/src/api-handlers/account/send-code.ts +70 -70
- package/src/api-handlers/account/update-phone.ts +84 -84
- package/src/api-handlers/account/validate-password.ts +139 -139
- package/src/api-handlers/account/verify-email.ts +134 -134
- package/src/api-handlers/account/verify-sms.ts +134 -134
- package/src/api-handlers/admin/analytics.ts +452 -452
- package/src/api-handlers/admin/audit.ts +223 -232
- package/src/api-handlers/admin/index.ts +63 -63
- package/src/api-handlers/admin/redis-sessions.ts +259 -259
- package/src/api-handlers/admin/sessions.ts +341 -327
- package/src/api-handlers/admin/site-logs.ts +388 -388
- package/src/api-handlers/admin/stats.ts +260 -260
- package/src/api-handlers/admin/users.ts +240 -251
- package/src/api-handlers/admin/vibe-data.ts +338 -333
- package/src/api-handlers/anon/preferences.ts +123 -123
- package/src/api-handlers/auth/credential-login-email-code.ts +92 -92
- package/src/api-handlers/auth/credential-login.ts +948 -948
- package/src/api-handlers/auth/jwks.ts +31 -31
- package/src/api-handlers/auth/login.ts +252 -252
- package/src/api-handlers/auth/passkey-signin.ts +116 -116
- package/src/api-handlers/auth/refresh.ts +829 -829
- package/src/api-handlers/auth/signout.ts +201 -201
- package/src/api-handlers/auth/status.ts +23 -23
- package/src/api-handlers/auth/update-session.ts +144 -144
- package/src/api-handlers/auth/validate.ts +45 -45
- package/src/api-handlers/auth/verify-code.ts +116 -116
- package/src/api-handlers/mfa/backup-code-verify.ts +170 -170
- package/src/api-handlers/mfa/backup-codes.ts +42 -42
- package/src/api-handlers/mfa/methods.ts +47 -47
- package/src/api-handlers/mfa/totp-confirm.ts +43 -43
- package/src/api-handlers/mfa/totp-enroll.ts +43 -43
- package/src/api-handlers/mfa/totp-verify.ts +172 -172
- package/src/api-handlers/oauth/resume.ts +182 -182
- package/src/api-handlers/onboarding/send-email-code.ts +18 -18
- package/src/api-handlers/onboarding/set-password.ts +21 -21
- package/src/api-handlers/onboarding/verify-code.ts +20 -20
- package/src/api-handlers/onboarding/verify-welcome-email.ts +17 -17
- package/src/api-handlers/passkeys/list.ts +32 -32
- package/src/api-handlers/passkeys/manage.ts +55 -55
- package/src/api-handlers/passkeys/register-options.ts +43 -43
- package/src/api-handlers/passkeys/register-verify.ts +42 -42
- package/src/api-handlers/session/refresh-viability.ts +56 -56
- package/src/api-handlers/session/viability.ts +238 -238
- package/src/api-handlers/test/force-expire.ts +167 -167
- package/src/auth/auth-decision.ts +292 -292
- package/src/auth/better-auth.ts +1688 -1688
- package/src/auth/idp-oauth.ts +310 -310
- package/src/auth/password-reset-bridge.ts +98 -98
- package/src/auth/revocation-fields.ts +16 -16
- package/src/auth/route-config.ts +236 -236
- package/src/auth/safe-callback.ts +199 -199
- package/src/auth/session-cookie-clear.ts +30 -30
- package/src/auth/session-reset-link.ts +159 -159
- package/src/auth/session-response-sanitizer.ts +151 -151
- package/src/auth/types/auth-types.ts +555 -555
- package/src/auth/types/index.ts +7 -7
- package/src/auth/unauthenticated-routes.ts +2 -2
- package/src/auth/utils/idp-client.ts +364 -364
- package/src/auth/utils/index.ts +6 -6
- package/src/auth/utils/token-utils.ts +243 -243
- package/src/client/AuthContext.tsx +192 -192
- package/src/client/better-auth-client.ts +70 -70
- package/src/client/fetch-with-auth.ts +47 -47
- package/src/client/fetchWithSession.ts +21 -21
- package/src/client/index.ts +13 -13
- package/src/client/useAnonSession.ts +131 -131
- package/src/components/SessionSync.tsx +138 -138
- package/src/components/SignalRHealthCheck.tsx +131 -131
- package/src/components/account/MobileNavDrawer.tsx +305 -305
- package/src/components/account/UserAvatarMenu.tsx +277 -277
- package/src/components/account/index.ts +13 -13
- package/src/components/admin/AlertSettingsTab.tsx +728 -728
- package/src/components/admin/AnalyticsTab.tsx +703 -703
- package/src/components/admin/DataBrowserTab.tsx +508 -508
- package/src/components/admin/LoggingSettingsTab.tsx +665 -665
- package/src/components/admin/SessionsTab.tsx +421 -421
- package/src/components/admin/StatsTab.tsx +379 -379
- package/src/components/admin/VibeAdminContext.tsx +87 -87
- package/src/components/admin/VibeAdminLayout.tsx +187 -187
- package/src/components/admin/index.ts +59 -59
- package/src/components/auth/CredentialSignInForm.tsx +240 -240
- package/src/components/auth/FederatedAuthSection.tsx +129 -129
- package/src/components/auth/ModeAwareLoginPage.tsx +146 -146
- package/src/components/auth/ModeAwareSignupPage.tsx +200 -200
- package/src/components/auth/PasswordResetBridge.tsx +30 -30
- package/src/components/auth/TraditionalAuthSection.tsx +103 -103
- package/src/components/recovery/CompleteStep.tsx +36 -36
- package/src/components/recovery/InitiateRecoveryStep.tsx +68 -68
- package/src/components/recovery/RequestedStep.tsx +30 -30
- package/src/components/recovery/SelectMethodStep.tsx +73 -73
- package/src/components/recovery/SetPasswordStep.tsx +118 -118
- package/src/components/recovery/VerifyCodeStep.tsx +90 -90
- package/src/components/reserved/ReservedRecoveryWarning.tsx +160 -160
- package/src/components/reserved/ReservedStatusBox.tsx +118 -118
- package/src/components/ui/BetaBadge.tsx +58 -58
- package/src/components/ui/Footer.tsx +93 -93
- package/src/config/env.ts +55 -55
- package/src/config/logger.ts +62 -62
- package/src/config/logging-config.ts +82 -82
- package/src/config/unauthenticated-routes.ts +19 -19
- package/src/config/vibe-log-transport.ts +264 -264
- package/src/edge/internal-api-url.ts +65 -65
- package/src/edge/middleware.ts +42 -42
- package/src/hooks/useAuth.ts +117 -117
- package/src/hooks/useAuthSettings.ts +109 -109
- package/src/hooks/useAvailableProviders.ts +143 -143
- package/src/hooks/usePasswordValidation.ts +127 -127
- package/src/hooks/useProfile.ts +82 -82
- package/src/hooks/usePublicAuthSettings.ts +171 -171
- package/src/hooks/useSessionExpiration.ts +101 -101
- package/src/hooks/useViabilitySession.ts +337 -337
- package/src/index.ts +64 -64
- package/src/lib/anon-session.ts +213 -213
- package/src/lib/api-handler.ts +643 -643
- package/src/lib/app-slug.ts +228 -228
- package/src/lib/authorize-resume.ts +172 -172
- package/src/lib/bearer-fetch.ts +31 -31
- package/src/lib/client-key.ts +88 -88
- package/src/lib/code-step-copy.ts +83 -83
- package/src/lib/credential-sign-in-client.ts +101 -101
- package/src/lib/demo-mode.ts +18 -18
- package/src/lib/device-id.ts +67 -67
- package/src/lib/ensure-fresh-access-token.ts +509 -509
- package/src/lib/geolocation.ts +265 -265
- package/src/lib/idp-client-config.ts +1005 -1005
- package/src/lib/idp-fetch.ts +169 -169
- package/src/lib/idp-url-guard.ts +37 -37
- package/src/lib/internal-api.ts +171 -171
- package/src/lib/jwt-decode-client.ts +45 -45
- package/src/lib/jwt-decode.ts +82 -82
- package/src/lib/lock-window.ts +49 -49
- package/src/lib/login-error-message.ts +41 -41
- package/src/lib/never-in-response.ts +64 -64
- package/src/lib/nextauth-secret.ts +168 -168
- package/src/lib/onboarding-proxy.ts +57 -57
- package/src/lib/password-rules.ts +50 -50
- package/src/lib/rate-limit-service.ts +9 -9
- package/src/lib/redis.ts +105 -105
- package/src/lib/refresh-token-validator.ts +64 -64
- package/src/lib/roles.ts +177 -177
- package/src/lib/safe-error-response.ts +149 -149
- package/src/lib/secret-validation.ts +8 -8
- package/src/lib/session-cookie-shape.ts +185 -185
- package/src/lib/session-store.ts +1092 -1092
- package/src/lib/session.ts +34 -34
- package/src/lib/single-flight.ts +64 -64
- package/src/lib/site-logger.ts +245 -245
- package/src/lib/standardized-client-api.ts +901 -901
- package/src/lib/startup-init.ts +276 -276
- package/src/lib/test-aware-get-token.ts +41 -41
- package/src/lib/token-expiry.ts +40 -40
- package/src/lib/token-lifecycle.ts +546 -546
- package/src/lib/token-log-id.ts +69 -69
- package/src/lib/twofa-rejection.ts +91 -91
- package/src/lib/types/api-responses.ts +336 -336
- package/src/lib/user-agent-parser.ts +252 -252
- package/src/logging/api/admin-analytics.ts +51 -51
- package/src/logging/api/audit-log.ts +53 -53
- package/src/logging/components/AdminAnalyticsLayout.tsx +49 -49
- package/src/logging/components/AuditLogViewer.tsx +125 -125
- package/src/logging/components/ErrorMetricsCard.tsx +98 -98
- package/src/logging/components/HealthMetricsCard.tsx +70 -70
- package/src/logging/hooks/useAdminAnalytics.ts +22 -22
- package/src/logging/hooks/useAuditLog.ts +24 -24
- package/src/logging/hooks/useErrorMetrics.ts +40 -40
- package/src/logging/hooks/useHealthMetrics.ts +44 -44
- package/src/logging/index.ts +18 -18
- package/src/logging/types/analytics.ts +81 -81
- package/src/logging/types/audit.ts +31 -31
- package/src/logging/types/index.ts +3 -3
- package/src/middleware/create-middleware.ts +1141 -1141
- package/src/middleware/rbac-check.ts +279 -279
- package/src/middleware/twofa-presets.ts +224 -224
- package/src/models/DecodedAccessToken.ts +16 -16
- package/src/models/SessionModel.ts +331 -331
- package/src/pages/admin-login/page.tsx +111 -111
- package/src/pages/admin-page-permissions/PagePermissionsAdminPage.tsx +527 -527
- package/src/pages/admin-page-permissions/index.ts +7 -7
- package/src/pages/admin-roles/RolesAdminPage.tsx +533 -533
- package/src/pages/admin-roles/index.ts +9 -9
- package/src/pages/admin-roles/modals.tsx +469 -469
- package/src/pages/client-admin/ClientSiteAdminPage.tsx +382 -382
- package/src/pages/client-admin/index.ts +33 -33
- package/src/pages/coming-soon/page.tsx +83 -83
- package/src/pages/login/page.tsx +338 -338
- package/src/pages/onboarding/index.ts +11 -11
- package/src/pages/onboarding/page.tsx +212 -212
- package/src/pages/profile/EnhancedProfilePage.tsx +514 -514
- package/src/pages/profile/index.ts +9 -9
- package/src/pages/profile/page.tsx +166 -166
- package/src/pages/recovery/page.tsx +267 -267
- package/src/pages/roles/MyRolesPage.tsx +211 -211
- package/src/pages/roles/components.tsx +294 -294
- package/src/pages/roles/index.ts +17 -17
- package/src/pages/security/EnhancedSecurityPage.tsx +660 -660
- package/src/pages/security/index.ts +12 -12
- package/src/pages/security/page.tsx +507 -507
- package/src/pages/service-unavailable/page.tsx +63 -63
- package/src/pages/settings/EnhancedSettingsPage.tsx +642 -642
- package/src/pages/settings/index.ts +9 -9
- package/src/pages/settings/page.tsx +47 -47
- package/src/pages/showcase/ShowcasePage.tsx +532 -532
- package/src/pages/showcase/index.ts +13 -13
- package/src/pages/test-env/EmergencyLogoutPage.tsx +192 -192
- package/src/pages/test-env/JwtInspectPage.tsx +449 -449
- package/src/pages/test-env/RefreshTokenPage.tsx +178 -178
- package/src/pages/test-env/TestEnvPage.tsx +130 -130
- package/src/pages/test-env/guarded.tsx +81 -81
- package/src/pages/test-env/index.ts +77 -77
- package/src/pages/test-env/redact-credentials.ts +96 -96
- package/src/pages/verify-code/page.tsx +746 -746
- package/src/routes/account/index.ts +31 -31
- package/src/routes/account/masked-info.ts +36 -36
- package/src/routes/account/send-code.ts +39 -39
- package/src/routes/account/update-phone.ts +13 -13
- package/src/routes/account/verify-email.ts +40 -40
- package/src/routes/account/verify-sms.ts +40 -40
- package/src/routes/auth/credential-login-email-code.ts +6 -6
- package/src/routes/auth/credential-login.ts +6 -6
- package/src/routes/auth/index.ts +22 -22
- package/src/routes/auth/logout.ts +111 -111
- package/src/routes/auth/nextauth.ts +45 -45
- package/src/routes/auth/passkey-signin.ts +13 -13
- package/src/routes/auth/refresh.ts +77 -77
- package/src/routes/auth/session-reset.ts +37 -37
- package/src/routes/auth/session.ts +261 -261
- package/src/routes/auth/settings.ts +181 -181
- package/src/routes/auth/viability.ts +519 -519
- package/src/routes/index.ts +17 -17
- package/src/routes/mfa/backup-code-verify.ts +1 -1
- package/src/routes/mfa/backup-codes.ts +10 -10
- package/src/routes/mfa/methods.ts +22 -22
- package/src/routes/mfa/totp-confirm.ts +10 -10
- package/src/routes/mfa/totp-enroll.ts +10 -10
- package/src/routes/mfa/totp-verify.ts +14 -14
- package/src/routes/onboarding/index.ts +15 -15
- package/src/routes/onboarding/send-email-code.ts +2 -2
- package/src/routes/onboarding/set-password.ts +2 -2
- package/src/routes/onboarding/verify-code.ts +2 -2
- package/src/routes/onboarding/verify-welcome-email.ts +2 -2
- package/src/routes/passkeys/list.ts +10 -10
- package/src/routes/passkeys/manage.ts +23 -23
- package/src/routes/passkeys/register-options.ts +10 -10
- package/src/routes/passkeys/register-verify.ts +10 -10
- package/src/routes/session/index.ts +7 -7
- package/src/routes/session/refresh-viability.ts +17 -17
- package/src/server/auth-guard.ts +203 -203
- package/src/server/auth.ts +486 -486
- package/src/server/decode-session.ts +309 -309
- package/src/server/slim-middleware.ts +117 -117
- package/src/server/verified-session-token.ts +103 -103
- package/src/server/with-auth.ts +93 -93
- package/src/services/signalrActivityService.ts +258 -258
- package/src/stores/authStore.ts +1900 -1900
- package/src/templates/instrumentation.ts +60 -60
- package/src/theme/ThemeProvider.tsx +39 -39
- package/src/theme/default.ts +33 -33
- package/src/theme/index.ts +31 -31
- package/src/theme/types.ts +69 -69
- package/src/theme/useTheme.ts +57 -57
- package/src/theme/utils.ts +40 -40
- package/src/types/api.ts +12 -12
- package/src/types/auth.d.ts +23 -23
- package/src/types/auth.ts +48 -48
- package/src/types/logging.ts +11 -11
- package/src/types/recovery.ts +54 -54
- package/src/utils/api.ts +401 -401
- package/src/utils/circuitBreaker.ts +40 -40
- package/src/utils/error-message.ts +108 -108
- package/src/utils/layout/reservedSpace.ts +124 -124
- package/src/utils/logout.ts +30 -30
- package/src/vibe/client.ts +878 -877
- package/src/vibe/enterprise-auth.ts +208 -208
- package/src/vibe/errors.ts +209 -209
- package/src/vibe/filters.ts +52 -0
- package/src/vibe/generic.ts +340 -339
- package/src/vibe/hooks/index.ts +367 -367
- package/src/vibe/index.ts +133 -133
- package/src/vibe/sessions.ts +925 -899
- package/src/vibe/types.ts +577 -577
package/src/vibe/errors.ts
CHANGED
|
@@ -1,209 +1,209 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* =============================================================================
|
|
3
|
-
* VIBE API ERROR CLASSES
|
|
4
|
-
* =============================================================================
|
|
5
|
-
*
|
|
6
|
-
* Typed error classes for Vibe API operations.
|
|
7
|
-
* These provide specific error handling for different failure scenarios.
|
|
8
|
-
*
|
|
9
|
-
* Usage:
|
|
10
|
-
* try {
|
|
11
|
-
* await vibe.users.findUnique({ where: { id: 123 } })
|
|
12
|
-
* } catch (error) {
|
|
13
|
-
* if (error instanceof VibeNotFoundError) {
|
|
14
|
-
* // Handle 404
|
|
15
|
-
* } else if (error instanceof VibeValidationError) {
|
|
16
|
-
* // Handle validation errors
|
|
17
|
-
* }
|
|
18
|
-
* }
|
|
19
|
-
*
|
|
20
|
-
* =============================================================================
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Base error class for all Vibe API errors
|
|
25
|
-
*/
|
|
26
|
-
export class VibeError extends Error {
|
|
27
|
-
public readonly code: string;
|
|
28
|
-
public readonly status: number;
|
|
29
|
-
public readonly details?: Record<string, unknown>;
|
|
30
|
-
|
|
31
|
-
constructor(
|
|
32
|
-
message: string,
|
|
33
|
-
code: string,
|
|
34
|
-
status: number,
|
|
35
|
-
details?: Record<string, unknown>
|
|
36
|
-
) {
|
|
37
|
-
super(message);
|
|
38
|
-
this.name = 'VibeError';
|
|
39
|
-
this.code = code;
|
|
40
|
-
this.status = status;
|
|
41
|
-
this.details = details;
|
|
42
|
-
|
|
43
|
-
// Maintains proper stack trace for where our error was thrown
|
|
44
|
-
if (Error.captureStackTrace) {
|
|
45
|
-
Error.captureStackTrace(this, VibeError);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
toJSON() {
|
|
50
|
-
return {
|
|
51
|
-
name: this.name,
|
|
52
|
-
message: this.message,
|
|
53
|
-
code: this.code,
|
|
54
|
-
status: this.status,
|
|
55
|
-
details: this.details,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
static fromResponse(response: {
|
|
60
|
-
success: false;
|
|
61
|
-
error: { code: string; message: string; details?: Record<string, unknown> };
|
|
62
|
-
}, status: number): VibeError {
|
|
63
|
-
const { code, message, details } = response.error;
|
|
64
|
-
|
|
65
|
-
switch (code) {
|
|
66
|
-
case 'NOT_FOUND':
|
|
67
|
-
case 'DOCUMENT_NOT_FOUND':
|
|
68
|
-
case 'TABLE_NOT_FOUND':
|
|
69
|
-
return new VibeNotFoundError(message, code, details);
|
|
70
|
-
|
|
71
|
-
case 'VALIDATION_ERROR':
|
|
72
|
-
case 'INVALID_INPUT':
|
|
73
|
-
return new VibeValidationError(message, details);
|
|
74
|
-
|
|
75
|
-
case 'UNAUTHORIZED':
|
|
76
|
-
case 'INVALID_CREDENTIALS':
|
|
77
|
-
case 'INVALID_CLIENT_ID':
|
|
78
|
-
return new VibeAuthError(message, code, details);
|
|
79
|
-
|
|
80
|
-
case 'RATE_LIMITED':
|
|
81
|
-
return new VibeRateLimitError(message, details);
|
|
82
|
-
|
|
83
|
-
case 'CONFLICT':
|
|
84
|
-
case 'DUPLICATE_ENTRY':
|
|
85
|
-
return new VibeConflictError(message, details);
|
|
86
|
-
|
|
87
|
-
default:
|
|
88
|
-
return new VibeError(message, code, status, details);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Thrown when a requested resource is not found (404)
|
|
95
|
-
*/
|
|
96
|
-
export class VibeNotFoundError extends VibeError {
|
|
97
|
-
constructor(
|
|
98
|
-
message: string = 'Resource not found',
|
|
99
|
-
code: string = 'NOT_FOUND',
|
|
100
|
-
details?: Record<string, unknown>
|
|
101
|
-
) {
|
|
102
|
-
super(message, code, 404, details);
|
|
103
|
-
this.name = 'VibeNotFoundError';
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Thrown when input validation fails (400)
|
|
109
|
-
*/
|
|
110
|
-
export class VibeValidationError extends VibeError {
|
|
111
|
-
public readonly fieldErrors?: Record<string, string[]>;
|
|
112
|
-
|
|
113
|
-
constructor(
|
|
114
|
-
message: string = 'Validation failed',
|
|
115
|
-
details?: Record<string, unknown>
|
|
116
|
-
) {
|
|
117
|
-
super(message, 'VALIDATION_ERROR', 400, details);
|
|
118
|
-
this.name = 'VibeValidationError';
|
|
119
|
-
|
|
120
|
-
// Extract field-level errors if present
|
|
121
|
-
if (details?.fieldErrors) {
|
|
122
|
-
this.fieldErrors = details.fieldErrors as Record<string, string[]>;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Thrown when authentication/authorization fails (401/403)
|
|
129
|
-
*/
|
|
130
|
-
export class VibeAuthError extends VibeError {
|
|
131
|
-
constructor(
|
|
132
|
-
message: string = 'Authentication required',
|
|
133
|
-
code: string = 'UNAUTHORIZED',
|
|
134
|
-
details?: Record<string, unknown>
|
|
135
|
-
) {
|
|
136
|
-
super(message, code, 401, details);
|
|
137
|
-
this.name = 'VibeAuthError';
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Thrown when rate limit is exceeded (429)
|
|
143
|
-
*/
|
|
144
|
-
export class VibeRateLimitError extends VibeError {
|
|
145
|
-
public readonly retryAfter?: number;
|
|
146
|
-
|
|
147
|
-
constructor(
|
|
148
|
-
message: string = 'Rate limit exceeded',
|
|
149
|
-
details?: Record<string, unknown>
|
|
150
|
-
) {
|
|
151
|
-
super(message, 'RATE_LIMITED', 429, details);
|
|
152
|
-
this.name = 'VibeRateLimitError';
|
|
153
|
-
|
|
154
|
-
// Extract retry-after if present
|
|
155
|
-
if (details?.retryAfter) {
|
|
156
|
-
this.retryAfter = details.retryAfter as number;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Thrown when there's a conflict (e.g., duplicate entry) (409)
|
|
163
|
-
*/
|
|
164
|
-
export class VibeConflictError extends VibeError {
|
|
165
|
-
constructor(
|
|
166
|
-
message: string = 'Resource conflict',
|
|
167
|
-
details?: Record<string, unknown>
|
|
168
|
-
) {
|
|
169
|
-
super(message, 'CONFLICT', 409, details);
|
|
170
|
-
this.name = 'VibeConflictError';
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Thrown when the Vibe API is unavailable (503)
|
|
176
|
-
*/
|
|
177
|
-
export class VibeServiceError extends VibeError {
|
|
178
|
-
constructor(
|
|
179
|
-
message: string = 'Vibe service unavailable',
|
|
180
|
-
details?: Record<string, unknown>
|
|
181
|
-
) {
|
|
182
|
-
super(message, 'SERVICE_UNAVAILABLE', 503, details);
|
|
183
|
-
this.name = 'VibeServiceError';
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* PAY-1767 (NightHawk 64534): thrown when a NON-ATOMIC `createMany` fails part-way. It CARRIES what was
|
|
189
|
-
* already created, so the caller can reconcile instead of guessing whether k-1 rows persisted. This is the
|
|
190
|
-
* point of the class: a partial write whose extent is invisible is the hazard, not the partial write itself.
|
|
191
|
-
*/
|
|
192
|
-
export class VibeBatchCreateError extends VibeError {
|
|
193
|
-
/** How many records were created before the failure. */
|
|
194
|
-
public readonly createdCount: number;
|
|
195
|
-
/** The document ids that were created before the failure. */
|
|
196
|
-
public readonly createdIds: Array<number | string>;
|
|
197
|
-
|
|
198
|
-
constructor(
|
|
199
|
-
message: string,
|
|
200
|
-
details: { createdCount: number; createdIds: Array<number | string>; failedIndex: number; total: number },
|
|
201
|
-
cause?: unknown,
|
|
202
|
-
) {
|
|
203
|
-
super(message, 'BATCH_PARTIAL_FAILURE', 500, details);
|
|
204
|
-
this.name = 'VibeBatchCreateError';
|
|
205
|
-
this.createdCount = details.createdCount;
|
|
206
|
-
this.createdIds = details.createdIds;
|
|
207
|
-
if (cause !== undefined) (this as { cause?: unknown }).cause = cause;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* =============================================================================
|
|
3
|
+
* VIBE API ERROR CLASSES
|
|
4
|
+
* =============================================================================
|
|
5
|
+
*
|
|
6
|
+
* Typed error classes for Vibe API operations.
|
|
7
|
+
* These provide specific error handling for different failure scenarios.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* try {
|
|
11
|
+
* await vibe.users.findUnique({ where: { id: 123 } })
|
|
12
|
+
* } catch (error) {
|
|
13
|
+
* if (error instanceof VibeNotFoundError) {
|
|
14
|
+
* // Handle 404
|
|
15
|
+
* } else if (error instanceof VibeValidationError) {
|
|
16
|
+
* // Handle validation errors
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* =============================================================================
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Base error class for all Vibe API errors
|
|
25
|
+
*/
|
|
26
|
+
export class VibeError extends Error {
|
|
27
|
+
public readonly code: string;
|
|
28
|
+
public readonly status: number;
|
|
29
|
+
public readonly details?: Record<string, unknown>;
|
|
30
|
+
|
|
31
|
+
constructor(
|
|
32
|
+
message: string,
|
|
33
|
+
code: string,
|
|
34
|
+
status: number,
|
|
35
|
+
details?: Record<string, unknown>
|
|
36
|
+
) {
|
|
37
|
+
super(message);
|
|
38
|
+
this.name = 'VibeError';
|
|
39
|
+
this.code = code;
|
|
40
|
+
this.status = status;
|
|
41
|
+
this.details = details;
|
|
42
|
+
|
|
43
|
+
// Maintains proper stack trace for where our error was thrown
|
|
44
|
+
if (Error.captureStackTrace) {
|
|
45
|
+
Error.captureStackTrace(this, VibeError);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
toJSON() {
|
|
50
|
+
return {
|
|
51
|
+
name: this.name,
|
|
52
|
+
message: this.message,
|
|
53
|
+
code: this.code,
|
|
54
|
+
status: this.status,
|
|
55
|
+
details: this.details,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static fromResponse(response: {
|
|
60
|
+
success: false;
|
|
61
|
+
error: { code: string; message: string; details?: Record<string, unknown> };
|
|
62
|
+
}, status: number): VibeError {
|
|
63
|
+
const { code, message, details } = response.error;
|
|
64
|
+
|
|
65
|
+
switch (code) {
|
|
66
|
+
case 'NOT_FOUND':
|
|
67
|
+
case 'DOCUMENT_NOT_FOUND':
|
|
68
|
+
case 'TABLE_NOT_FOUND':
|
|
69
|
+
return new VibeNotFoundError(message, code, details);
|
|
70
|
+
|
|
71
|
+
case 'VALIDATION_ERROR':
|
|
72
|
+
case 'INVALID_INPUT':
|
|
73
|
+
return new VibeValidationError(message, details);
|
|
74
|
+
|
|
75
|
+
case 'UNAUTHORIZED':
|
|
76
|
+
case 'INVALID_CREDENTIALS':
|
|
77
|
+
case 'INVALID_CLIENT_ID':
|
|
78
|
+
return new VibeAuthError(message, code, details);
|
|
79
|
+
|
|
80
|
+
case 'RATE_LIMITED':
|
|
81
|
+
return new VibeRateLimitError(message, details);
|
|
82
|
+
|
|
83
|
+
case 'CONFLICT':
|
|
84
|
+
case 'DUPLICATE_ENTRY':
|
|
85
|
+
return new VibeConflictError(message, details);
|
|
86
|
+
|
|
87
|
+
default:
|
|
88
|
+
return new VibeError(message, code, status, details);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Thrown when a requested resource is not found (404)
|
|
95
|
+
*/
|
|
96
|
+
export class VibeNotFoundError extends VibeError {
|
|
97
|
+
constructor(
|
|
98
|
+
message: string = 'Resource not found',
|
|
99
|
+
code: string = 'NOT_FOUND',
|
|
100
|
+
details?: Record<string, unknown>
|
|
101
|
+
) {
|
|
102
|
+
super(message, code, 404, details);
|
|
103
|
+
this.name = 'VibeNotFoundError';
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Thrown when input validation fails (400)
|
|
109
|
+
*/
|
|
110
|
+
export class VibeValidationError extends VibeError {
|
|
111
|
+
public readonly fieldErrors?: Record<string, string[]>;
|
|
112
|
+
|
|
113
|
+
constructor(
|
|
114
|
+
message: string = 'Validation failed',
|
|
115
|
+
details?: Record<string, unknown>
|
|
116
|
+
) {
|
|
117
|
+
super(message, 'VALIDATION_ERROR', 400, details);
|
|
118
|
+
this.name = 'VibeValidationError';
|
|
119
|
+
|
|
120
|
+
// Extract field-level errors if present
|
|
121
|
+
if (details?.fieldErrors) {
|
|
122
|
+
this.fieldErrors = details.fieldErrors as Record<string, string[]>;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Thrown when authentication/authorization fails (401/403)
|
|
129
|
+
*/
|
|
130
|
+
export class VibeAuthError extends VibeError {
|
|
131
|
+
constructor(
|
|
132
|
+
message: string = 'Authentication required',
|
|
133
|
+
code: string = 'UNAUTHORIZED',
|
|
134
|
+
details?: Record<string, unknown>
|
|
135
|
+
) {
|
|
136
|
+
super(message, code, 401, details);
|
|
137
|
+
this.name = 'VibeAuthError';
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Thrown when rate limit is exceeded (429)
|
|
143
|
+
*/
|
|
144
|
+
export class VibeRateLimitError extends VibeError {
|
|
145
|
+
public readonly retryAfter?: number;
|
|
146
|
+
|
|
147
|
+
constructor(
|
|
148
|
+
message: string = 'Rate limit exceeded',
|
|
149
|
+
details?: Record<string, unknown>
|
|
150
|
+
) {
|
|
151
|
+
super(message, 'RATE_LIMITED', 429, details);
|
|
152
|
+
this.name = 'VibeRateLimitError';
|
|
153
|
+
|
|
154
|
+
// Extract retry-after if present
|
|
155
|
+
if (details?.retryAfter) {
|
|
156
|
+
this.retryAfter = details.retryAfter as number;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Thrown when there's a conflict (e.g., duplicate entry) (409)
|
|
163
|
+
*/
|
|
164
|
+
export class VibeConflictError extends VibeError {
|
|
165
|
+
constructor(
|
|
166
|
+
message: string = 'Resource conflict',
|
|
167
|
+
details?: Record<string, unknown>
|
|
168
|
+
) {
|
|
169
|
+
super(message, 'CONFLICT', 409, details);
|
|
170
|
+
this.name = 'VibeConflictError';
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Thrown when the Vibe API is unavailable (503)
|
|
176
|
+
*/
|
|
177
|
+
export class VibeServiceError extends VibeError {
|
|
178
|
+
constructor(
|
|
179
|
+
message: string = 'Vibe service unavailable',
|
|
180
|
+
details?: Record<string, unknown>
|
|
181
|
+
) {
|
|
182
|
+
super(message, 'SERVICE_UNAVAILABLE', 503, details);
|
|
183
|
+
this.name = 'VibeServiceError';
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* PAY-1767 (NightHawk 64534): thrown when a NON-ATOMIC `createMany` fails part-way. It CARRIES what was
|
|
189
|
+
* already created, so the caller can reconcile instead of guessing whether k-1 rows persisted. This is the
|
|
190
|
+
* point of the class: a partial write whose extent is invisible is the hazard, not the partial write itself.
|
|
191
|
+
*/
|
|
192
|
+
export class VibeBatchCreateError extends VibeError {
|
|
193
|
+
/** How many records were created before the failure. */
|
|
194
|
+
public readonly createdCount: number;
|
|
195
|
+
/** The document ids that were created before the failure. */
|
|
196
|
+
public readonly createdIds: Array<number | string>;
|
|
197
|
+
|
|
198
|
+
constructor(
|
|
199
|
+
message: string,
|
|
200
|
+
details: { createdCount: number; createdIds: Array<number | string>; failedIndex: number; total: number },
|
|
201
|
+
cause?: unknown,
|
|
202
|
+
) {
|
|
203
|
+
super(message, 'BATCH_PARTIAL_FAILURE', 500, details);
|
|
204
|
+
this.name = 'VibeBatchCreateError';
|
|
205
|
+
this.createdCount = details.createdCount;
|
|
206
|
+
this.createdIds = details.createdIds;
|
|
207
|
+
if (cause !== undefined) (this as { cause?: unknown }).cause = cause;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PAY-1810: the ONE place the package builds Vibe /query filters and orderBy, in the shapes Core's VibeQueryBuilder accepts.
|
|
3
|
+
*
|
|
4
|
+
* Core accepts exactly three filter forms (PayEz.Vibe.Public.Api VibeQueryModels / VibeQueryBuilder):
|
|
5
|
+
* standard { field: { op: value } } with AND / OR arrays
|
|
6
|
+
* flat { field, operator, value }
|
|
7
|
+
* compound { operator: 'and' | 'or', filters: [ ...nodes ] } <- the key is `filters`, NOT `conditions`
|
|
8
|
+
* What goes wrong with the shapes this module replaces:
|
|
9
|
+
* - { operator, conditions } has no `filters` key, so Core reads `operator` / `conditions` as COLUMN names and returns ZERO rows
|
|
10
|
+
* (a broken search; for revoke-all, "revoked 0 sessions" reported as success).
|
|
11
|
+
* - operator 'like' is not a Core operator; in a flat filter it is DROPPED and the query returns ALL rows. Core's substring operator is
|
|
12
|
+
* `contains` (ILIKE, case-insensitive); `ilike` is case-insensitive EQUALS.
|
|
13
|
+
* - orderBy must be a { field: 'asc' | 'desc' } map (Core's model is Dictionary<string,string>); a bare string is rejected or ignored, never honoured.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export type VibeOperator = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'startsWith' | 'endsWith' | 'ilike' | 'in' | 'notIn';
|
|
17
|
+
|
|
18
|
+
export interface VibeFlatFilter {
|
|
19
|
+
field: string;
|
|
20
|
+
operator: VibeOperator;
|
|
21
|
+
value: unknown;
|
|
22
|
+
}
|
|
23
|
+
export interface VibeCompoundFilter {
|
|
24
|
+
operator: 'and' | 'or';
|
|
25
|
+
filters: VibeFilter[];
|
|
26
|
+
}
|
|
27
|
+
export type VibeFilter = VibeFlatFilter | VibeCompoundFilter;
|
|
28
|
+
|
|
29
|
+
export const eq = (field: string, value: unknown): VibeFlatFilter => ({ field, operator: 'eq', value });
|
|
30
|
+
export const gte = (field: string, value: unknown): VibeFlatFilter => ({ field, operator: 'gte', value });
|
|
31
|
+
export const lte = (field: string, value: unknown): VibeFlatFilter => ({ field, operator: 'lte', value });
|
|
32
|
+
/** Case-insensitive substring (Core `contains` = ILIKE). The value is the bare text: no % wildcards. */
|
|
33
|
+
export const contains = (field: string, value: string): VibeFlatFilter => ({ field, operator: 'contains', value });
|
|
34
|
+
|
|
35
|
+
/** AND of the given nodes: none -> undefined (no filter), one -> that node, several -> a compound with `filters`. */
|
|
36
|
+
export function allOf(nodes: Array<VibeFilter | undefined | null>): VibeFilter | undefined {
|
|
37
|
+
const f = nodes.filter((n): n is VibeFilter => !!n);
|
|
38
|
+
if (f.length === 0) return undefined;
|
|
39
|
+
return f.length === 1 ? f[0] : { operator: 'and', filters: f };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** OR of the given nodes: none -> undefined, one -> that node, several -> a compound with `filters`. */
|
|
43
|
+
export function anyOf(nodes: Array<VibeFilter | undefined | null>): VibeFilter | undefined {
|
|
44
|
+
const f = nodes.filter((n): n is VibeFilter => !!n);
|
|
45
|
+
if (f.length === 0) return undefined;
|
|
46
|
+
return f.length === 1 ? f[0] : { operator: 'or', filters: f };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** orderBy as Core binds it. */
|
|
50
|
+
export function orderByMap(field: string, direction: 'asc' | 'desc' = 'desc'): Record<string, 'asc' | 'desc'> {
|
|
51
|
+
return { [field]: direction };
|
|
52
|
+
}
|