@geenius/tools 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +62 -3
- package/packages/convex/shared/README.md +1 -1
- package/packages/devtools/dist/index.d.ts +204 -0
- package/packages/devtools/dist/index.js +186 -0
- package/packages/devtools/dist/index.js.map +1 -0
- package/packages/devtools/react/README.md +1 -1
- package/packages/devtools/solidjs/README.md +1 -1
- package/packages/devtools/solidjs/dist/index.js +1830 -0
- package/packages/devtools/solidjs/dist/index.js.map +1 -0
- package/packages/env/dist/index.d.ts +151 -0
- package/packages/env/dist/index.js +93 -0
- package/packages/env/dist/index.js.map +1 -0
- package/packages/errors/dist/index.d.ts +177 -0
- package/packages/errors/dist/index.js +187 -0
- package/packages/errors/dist/index.js.map +1 -0
- package/packages/errors/react/README.md +1 -1
- package/packages/errors/solidjs/README.md +1 -1
- package/packages/logger/dist/index.d.ts +171 -0
- package/packages/logger/dist/index.js +216 -0
- package/packages/logger/dist/index.js.map +1 -0
- package/packages/logger/react/README.md +1 -1
- package/packages/logger/solidjs/README.md +1 -1
- package/packages/perf/dist/index.d.ts +168 -0
- package/packages/perf/dist/index.js +265 -0
- package/packages/perf/dist/index.js.map +1 -0
- package/packages/perf/react/README.md +1 -1
- package/packages/perf/solidjs/README.md +1 -1
- package/packages/shared/dist/index.d.ts +253 -0
- package/packages/shared/dist/index.js +278 -0
- package/packages/shared/dist/index.js.map +1 -0
- package/.changeset/config.json +0 -11
- package/.env.example +0 -2
- package/.github/CODEOWNERS +0 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -16
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -11
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -10
- package/.github/dependabot.yml +0 -11
- package/.github/workflows/ci.yml +0 -23
- package/.github/workflows/release.yml +0 -29
- package/.node-version +0 -1
- package/.nvmrc +0 -1
- package/.prettierrc +0 -7
- package/.project/ACCOUNT.yaml +0 -4
- package/.project/IDEAS.yaml +0 -7
- package/.project/PROJECT.yaml +0 -11
- package/.project/ROADMAP.yaml +0 -15
- package/CODE_OF_CONDUCT.md +0 -26
- package/CONTRIBUTING.md +0 -69
- package/SECURITY.md +0 -18
- package/SUPPORT.md +0 -14
- package/packages/convex/shared/package.json +0 -42
- package/packages/convex/shared/src/audit/index.ts +0 -5
- package/packages/convex/shared/src/audit/presets.ts +0 -165
- package/packages/convex/shared/src/audit/schema.ts +0 -85
- package/packages/convex/shared/src/audit/write.ts +0 -102
- package/packages/convex/shared/src/extract.ts +0 -75
- package/packages/convex/shared/src/index.ts +0 -41
- package/packages/convex/shared/src/messages.ts +0 -45
- package/packages/convex/shared/src/security.ts +0 -112
- package/packages/convex/shared/src/throw.ts +0 -184
- package/packages/convex/shared/src/types.ts +0 -57
- package/packages/convex/shared/src/utils.ts +0 -58
- package/packages/convex/shared/tsconfig.json +0 -28
- package/packages/convex/shared/tsup.config.ts +0 -12
- package/packages/devtools/package.json +0 -27
- package/packages/devtools/react/package.json +0 -53
- package/packages/devtools/react/src/components/DesignPreview.tsx +0 -59
- package/packages/devtools/react/src/components/DesignSwitcherDropdown.tsx +0 -99
- package/packages/devtools/react/src/components/DevSidebar.tsx +0 -247
- package/packages/devtools/react/src/components/DevToolbar.tsx +0 -242
- package/packages/devtools/react/src/components/GitHubIssueDialog.tsx +0 -402
- package/packages/devtools/react/src/components/InspectorOverlay.tsx +0 -312
- package/packages/devtools/react/src/components/PageLoadWaterfall.tsx +0 -144
- package/packages/devtools/react/src/components/PerformancePanel.tsx +0 -330
- package/packages/devtools/react/src/context/DevModeContext.tsx +0 -226
- package/packages/devtools/react/src/context/PerformanceContext.tsx +0 -143
- package/packages/devtools/react/src/data/designs.ts +0 -13
- package/packages/devtools/react/src/hooks/useGitHubLabels.ts +0 -47
- package/packages/devtools/react/src/hooks/useVirtualList.ts +0 -124
- package/packages/devtools/react/src/index.ts +0 -77
- package/packages/devtools/react/src/panels/ConvexSpy.tsx +0 -130
- package/packages/devtools/react/src/panels/DatabaseSeeder.tsx +0 -116
- package/packages/devtools/react/src/panels/DevModePhase2.tsx +0 -191
- package/packages/devtools/react/src/panels/DevModePhase3.tsx +0 -234
- package/packages/devtools/react/src/panels/FeatureFlagsToggle.tsx +0 -104
- package/packages/devtools/react/src/panels/QuickRouteJump.tsx +0 -152
- package/packages/devtools/react/src/services/github-service.ts +0 -247
- package/packages/devtools/react/tsconfig.json +0 -31
- package/packages/devtools/react/tsup.config.ts +0 -18
- package/packages/devtools/solidjs/package.json +0 -49
- package/packages/devtools/solidjs/src/components/DesignPreview.tsx +0 -51
- package/packages/devtools/solidjs/src/components/DesignSwitcherDropdown.tsx +0 -95
- package/packages/devtools/solidjs/src/components/DevSidebar.tsx +0 -247
- package/packages/devtools/solidjs/src/components/DevToolbar.tsx +0 -242
- package/packages/devtools/solidjs/src/components/GitHubIssueDialog.tsx +0 -400
- package/packages/devtools/solidjs/src/components/InspectorOverlay.tsx +0 -311
- package/packages/devtools/solidjs/src/components/PageLoadWaterfall.tsx +0 -144
- package/packages/devtools/solidjs/src/components/PerformancePanel.tsx +0 -330
- package/packages/devtools/solidjs/src/context/DevModeContext.tsx +0 -216
- package/packages/devtools/solidjs/src/context/PerformanceContext.tsx +0 -135
- package/packages/devtools/solidjs/src/data/designs.ts +0 -13
- package/packages/devtools/solidjs/src/hooks/createGitHubLabels.ts +0 -47
- package/packages/devtools/solidjs/src/index.ts +0 -64
- package/packages/devtools/solidjs/src/services/github-service.ts +0 -247
- package/packages/devtools/solidjs/tsconfig.json +0 -21
- package/packages/devtools/src/index.ts +0 -377
- package/packages/devtools/tsup.config.ts +0 -12
- package/packages/env/package.json +0 -30
- package/packages/env/src/index.ts +0 -264
- package/packages/env/tsup.config.ts +0 -12
- package/packages/errors/package.json +0 -27
- package/packages/errors/react/package.json +0 -72
- package/packages/errors/react/src/analytics.ts +0 -16
- package/packages/errors/react/src/components/ErrorBoundary.tsx +0 -248
- package/packages/errors/react/src/components/ErrorDisplay.tsx +0 -328
- package/packages/errors/react/src/components/ValidationErrors.tsx +0 -102
- package/packages/errors/react/src/config.ts +0 -199
- package/packages/errors/react/src/constants.ts +0 -74
- package/packages/errors/react/src/hooks/useErrorBoundary.ts +0 -92
- package/packages/errors/react/src/hooks/useErrorHandler.ts +0 -87
- package/packages/errors/react/src/index.ts +0 -96
- package/packages/errors/react/src/types.ts +0 -102
- package/packages/errors/react/src/utils/errorMessages.ts +0 -35
- package/packages/errors/react/src/utils/errorPolicy.ts +0 -139
- package/packages/errors/react/src/utils/extractAppError.ts +0 -174
- package/packages/errors/react/src/utils/formatError.ts +0 -112
- package/packages/errors/react/tsconfig.json +0 -25
- package/packages/errors/react/tsup.config.ts +0 -24
- package/packages/errors/solidjs/package.json +0 -46
- package/packages/errors/solidjs/src/components/ErrorDisplay.tsx +0 -179
- package/packages/errors/solidjs/src/config.ts +0 -98
- package/packages/errors/solidjs/src/hooks/createErrorHandler.ts +0 -107
- package/packages/errors/solidjs/src/index.ts +0 -61
- package/packages/errors/solidjs/src/types.ts +0 -34
- package/packages/errors/solidjs/src/utils/errorPolicy.ts +0 -56
- package/packages/errors/solidjs/src/utils/extractAppError.ts +0 -94
- package/packages/errors/solidjs/src/utils/formatError.ts +0 -33
- package/packages/errors/solidjs/tsconfig.json +0 -26
- package/packages/errors/solidjs/tsup.config.ts +0 -21
- package/packages/errors/src/index.ts +0 -320
- package/packages/errors/tsup.config.ts +0 -12
- package/packages/logger/package.json +0 -27
- package/packages/logger/react/package.json +0 -46
- package/packages/logger/react/src/index.ts +0 -4
- package/packages/logger/react/src/useMetrics.ts +0 -42
- package/packages/logger/react/src/usePerformanceLog.ts +0 -61
- package/packages/logger/react/tsconfig.json +0 -31
- package/packages/logger/react/tsup.config.ts +0 -12
- package/packages/logger/solidjs/package.json +0 -45
- package/packages/logger/solidjs/src/createMetrics.ts +0 -37
- package/packages/logger/solidjs/src/createPerformanceLog.ts +0 -58
- package/packages/logger/solidjs/src/index.ts +0 -4
- package/packages/logger/solidjs/tsconfig.json +0 -32
- package/packages/logger/solidjs/tsup.config.ts +0 -12
- package/packages/logger/src/index.ts +0 -363
- package/packages/logger/tsup.config.ts +0 -12
- package/packages/perf/package.json +0 -27
- package/packages/perf/react/package.json +0 -59
- package/packages/perf/react/src/components/PerformanceDashboard.tsx +0 -257
- package/packages/perf/react/src/hooks/useMonitoredQuery.ts +0 -89
- package/packages/perf/react/src/hooks/usePerformanceMetrics.ts +0 -78
- package/packages/perf/react/src/index.ts +0 -33
- package/packages/perf/react/src/services/PerformanceMonitor.ts +0 -313
- package/packages/perf/react/src/types.ts +0 -77
- package/packages/perf/react/tsconfig.json +0 -25
- package/packages/perf/react/tsup.config.ts +0 -19
- package/packages/perf/solidjs/package.json +0 -41
- package/packages/perf/solidjs/src/components/PerformanceDashboard.tsx +0 -207
- package/packages/perf/solidjs/src/hooks/createPerformanceMetrics.ts +0 -73
- package/packages/perf/solidjs/src/index.ts +0 -31
- package/packages/perf/solidjs/src/services/PerformanceMonitor.ts +0 -134
- package/packages/perf/solidjs/src/types.ts +0 -78
- package/packages/perf/solidjs/tsconfig.json +0 -26
- package/packages/perf/solidjs/tsup.config.ts +0 -14
- package/packages/perf/src/index.ts +0 -410
- package/packages/perf/tsup.config.ts +0 -12
- package/pnpm-workspace.yaml +0 -2
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
// @geenius-tools/convex-errors — src/extract.ts
|
|
2
|
-
|
|
3
|
-
import { ConvexError } from 'convex/values'
|
|
4
|
-
import type { AppErrorCode, AppErrorPayload, ValidationError } from './types'
|
|
5
|
-
import { HTTP_STATUS_MAP } from './types'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Check if an error is a ConvexError with AppErrorPayload.
|
|
9
|
-
*/
|
|
10
|
-
export function isAppError(error: unknown): error is ConvexError<AppErrorPayload> {
|
|
11
|
-
return error instanceof ConvexError && typeof (error.data as AppErrorPayload)?.code === 'string'
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Extract AppErrorPayload from a ConvexError, or return null.
|
|
16
|
-
*/
|
|
17
|
-
export function extractAppError(error: unknown): AppErrorPayload | null {
|
|
18
|
-
if (isAppError(error)) {
|
|
19
|
-
return error.data
|
|
20
|
-
}
|
|
21
|
-
return null
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Get the error code from a ConvexError, or 'INTERNAL' as fallback.
|
|
26
|
-
*/
|
|
27
|
-
export function getErrorCode(error: unknown): AppErrorCode {
|
|
28
|
-
const payload = extractAppError(error)
|
|
29
|
-
return payload?.code ?? 'INTERNAL'
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Get the error message from a ConvexError, or a fallback string.
|
|
34
|
-
*/
|
|
35
|
-
export function getErrorMsg(error: unknown, fallback = 'An unexpected error occurred'): string {
|
|
36
|
-
const payload = extractAppError(error)
|
|
37
|
-
return payload?.message ?? (error instanceof Error ? error.message : fallback)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Get validation errors from a ConvexError, or empty array.
|
|
42
|
-
*/
|
|
43
|
-
export function getValidationErrors(error: unknown): ValidationError[] {
|
|
44
|
-
const payload = extractAppError(error)
|
|
45
|
-
return payload?.validationErrors ?? []
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Get HTTP status code for a ConvexError.
|
|
50
|
-
*/
|
|
51
|
-
export function getHttpStatus(error: unknown): number {
|
|
52
|
-
const code = getErrorCode(error)
|
|
53
|
-
return HTTP_STATUS_MAP[code] ?? 500
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Convert an error to a JSON-serializable response object.
|
|
58
|
-
* Useful for HTTP error responses.
|
|
59
|
-
*/
|
|
60
|
-
export function toErrorResponse(error: unknown): {
|
|
61
|
-
status: number
|
|
62
|
-
body: { error: AppErrorPayload }
|
|
63
|
-
} {
|
|
64
|
-
const payload = extractAppError(error)
|
|
65
|
-
const code = payload?.code ?? 'INTERNAL'
|
|
66
|
-
return {
|
|
67
|
-
status: HTTP_STATUS_MAP[code] ?? 500,
|
|
68
|
-
body: {
|
|
69
|
-
error: payload ?? {
|
|
70
|
-
code: 'INTERNAL',
|
|
71
|
-
message: error instanceof Error ? error.message : 'Unknown error',
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
}
|
|
75
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
// @geenius-tools/convex-errors — src/index.ts
|
|
2
|
-
|
|
3
|
-
// Types
|
|
4
|
-
export type {
|
|
5
|
-
AppErrorCode,
|
|
6
|
-
AppErrorPayload,
|
|
7
|
-
ValidationError,
|
|
8
|
-
} from './types'
|
|
9
|
-
export { HTTP_STATUS_MAP } from './types'
|
|
10
|
-
|
|
11
|
-
// Error throwers
|
|
12
|
-
export {
|
|
13
|
-
unauthenticated,
|
|
14
|
-
forbidden,
|
|
15
|
-
notFound,
|
|
16
|
-
badRequest,
|
|
17
|
-
conflict,
|
|
18
|
-
internal,
|
|
19
|
-
featureDisabled,
|
|
20
|
-
rateLimited,
|
|
21
|
-
validationError,
|
|
22
|
-
withErrorMeta,
|
|
23
|
-
} from './throw'
|
|
24
|
-
|
|
25
|
-
// Error messages
|
|
26
|
-
export {
|
|
27
|
-
DEFAULT_ERROR_MESSAGES,
|
|
28
|
-
configureErrorMessages,
|
|
29
|
-
getErrorMessage,
|
|
30
|
-
} from './messages'
|
|
31
|
-
|
|
32
|
-
// Error extraction (for frontend)
|
|
33
|
-
export {
|
|
34
|
-
isAppError,
|
|
35
|
-
extractAppError,
|
|
36
|
-
getErrorCode,
|
|
37
|
-
getErrorMsg,
|
|
38
|
-
getValidationErrors,
|
|
39
|
-
getHttpStatus,
|
|
40
|
-
toErrorResponse,
|
|
41
|
-
} from './extract'
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// @geenius-tools/convex-errors — src/messages.ts
|
|
2
|
-
|
|
3
|
-
import type { AppErrorCode } from './types'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Default English error messages.
|
|
7
|
-
* Override these by passing your own messages to `configureErrorMessages()`.
|
|
8
|
-
*/
|
|
9
|
-
export const DEFAULT_ERROR_MESSAGES: Record<AppErrorCode, string> = {
|
|
10
|
-
UNAUTHENTICATED: 'Please sign in to continue.',
|
|
11
|
-
FORBIDDEN: 'You do not have permission for this action.',
|
|
12
|
-
NOT_FOUND: 'The requested resource was not found.',
|
|
13
|
-
BAD_REQUEST: 'Invalid request. Please check your input.',
|
|
14
|
-
CONFLICT: 'Action not possible (conflict with existing data).',
|
|
15
|
-
INTERNAL: 'An internal error occurred. Please try again later.',
|
|
16
|
-
VALIDATION_ERROR: 'Please check your input and try again.',
|
|
17
|
-
RATE_LIMITED: 'Too many requests. Please try again later.',
|
|
18
|
-
FEATURE_DISABLED: 'This feature is currently disabled.',
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
let currentMessages: Record<AppErrorCode, string> = { ...DEFAULT_ERROR_MESSAGES }
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Override default error messages (e.g., for i18n / localization).
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```ts
|
|
28
|
-
* configureErrorMessages({
|
|
29
|
-
* UNAUTHENTICATED: 'Bitte melde dich an, um fortzufahren.',
|
|
30
|
-
* FORBIDDEN: 'Du hast keine Berechtigung für diese Aktion.',
|
|
31
|
-
* })
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
export function configureErrorMessages(
|
|
35
|
-
messages: Partial<Record<AppErrorCode, string>>,
|
|
36
|
-
): void {
|
|
37
|
-
currentMessages = { ...currentMessages, ...messages }
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Get the current error message for a given code.
|
|
42
|
-
*/
|
|
43
|
-
export function getErrorMessage(code: AppErrorCode): string {
|
|
44
|
-
return currentMessages[code]
|
|
45
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
// @geenius-tools/convex-wrappers — src/security.ts
|
|
2
|
-
|
|
3
|
-
import type { RateLimitConfig, PrivacyConfig } from './types'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Simple in-memory rate limiter for development/prototyping.
|
|
7
|
-
* In production, you'd want to use Convex's built-in rate limiting
|
|
8
|
-
* or a persistent store.
|
|
9
|
-
*
|
|
10
|
-
* This provides the core rate limit checking logic.
|
|
11
|
-
* The actual Convex integration is left to the consumer to wire up.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* import { checkRateLimit } from '@geenius-tools/convex-wrappers'
|
|
16
|
-
*
|
|
17
|
-
* // In your mutation wrapper:
|
|
18
|
-
* const isAllowed = checkRateLimit({
|
|
19
|
-
* key: userId,
|
|
20
|
-
* maxRequests: 10,
|
|
21
|
-
* windowMs: 60_000,
|
|
22
|
-
* })
|
|
23
|
-
* if (!isAllowed) {
|
|
24
|
-
* rateLimited('Too many requests')
|
|
25
|
-
* }
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
const rateLimitStore = new Map<string, { count: number; resetAt: number }>()
|
|
29
|
-
|
|
30
|
-
export function checkRateLimit(params: {
|
|
31
|
-
key: string
|
|
32
|
-
maxRequests: number
|
|
33
|
-
windowMs: number
|
|
34
|
-
}): boolean {
|
|
35
|
-
const { key, maxRequests, windowMs } = params
|
|
36
|
-
const now = Date.now()
|
|
37
|
-
const entry = rateLimitStore.get(key)
|
|
38
|
-
|
|
39
|
-
if (!entry || now > entry.resetAt) {
|
|
40
|
-
rateLimitStore.set(key, { count: 1, resetAt: now + windowMs })
|
|
41
|
-
return true
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (entry.count >= maxRequests) {
|
|
45
|
-
return false
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
entry.count++
|
|
49
|
-
return true
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Clear rate limit for a specific key (e.g., after successful auth).
|
|
54
|
-
*/
|
|
55
|
-
export function clearRateLimit(key: string): void {
|
|
56
|
-
rateLimitStore.delete(key)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Validate that a user has one of the required roles.
|
|
61
|
-
*/
|
|
62
|
-
export function requireRoles(
|
|
63
|
-
user: { role?: string; roleType?: string; roles?: string[] },
|
|
64
|
-
requiredRoles: readonly string[],
|
|
65
|
-
): void {
|
|
66
|
-
const userRoles = [
|
|
67
|
-
user.role,
|
|
68
|
-
user.roleType,
|
|
69
|
-
...(user.roles ?? []),
|
|
70
|
-
].filter(Boolean) as string[]
|
|
71
|
-
|
|
72
|
-
const hasRole = requiredRoles.some((r) => userRoles.includes(r))
|
|
73
|
-
if (!hasRole) {
|
|
74
|
-
throw new Error(
|
|
75
|
-
`Forbidden: user has roles [${userRoles.join(', ')}] but needs one of [${requiredRoles.join(', ')}]`,
|
|
76
|
-
)
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Redact args based on privacy config.
|
|
82
|
-
*/
|
|
83
|
-
export function redactArgs(
|
|
84
|
-
args: Record<string, unknown>,
|
|
85
|
-
privacy: PrivacyConfig,
|
|
86
|
-
): Record<string, unknown> {
|
|
87
|
-
if (privacy.mode === 'none') return args
|
|
88
|
-
|
|
89
|
-
const sensitive = new Set(
|
|
90
|
-
privacy.sensitiveFields ?? ['password', 'token', 'secret', 'apiKey'],
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
const result: Record<string, unknown> = {}
|
|
94
|
-
for (const [key, value] of Object.entries(args)) {
|
|
95
|
-
if (sensitive.has(key)) {
|
|
96
|
-
result[key] = privacy.mode === 'hash' ? `[HASHED:${hashSimple(String(value))}]` : '[REDACTED]'
|
|
97
|
-
} else {
|
|
98
|
-
result[key] = value
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return result
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function hashSimple(input: string): string {
|
|
105
|
-
let hash = 0
|
|
106
|
-
for (let i = 0; i < input.length; i++) {
|
|
107
|
-
const char = input.charCodeAt(i)
|
|
108
|
-
hash = (hash << 5) - hash + char
|
|
109
|
-
hash |= 0
|
|
110
|
-
}
|
|
111
|
-
return Math.abs(hash).toString(36)
|
|
112
|
-
}
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
// @geenius-tools/convex-errors — src/throw.ts
|
|
2
|
-
|
|
3
|
-
import { ConvexError, type Value } from 'convex/values'
|
|
4
|
-
import type { AppErrorCode, AppErrorPayload, ValidationError } from './types'
|
|
5
|
-
import { getErrorMessage } from './messages'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Internal function to throw a ConvexError with AppErrorPayload.
|
|
9
|
-
*/
|
|
10
|
-
function throwAppError(
|
|
11
|
-
code: AppErrorCode,
|
|
12
|
-
message?: string,
|
|
13
|
-
details?: Record<string, Value>,
|
|
14
|
-
validationErrors?: ValidationError[],
|
|
15
|
-
metadata?: AppErrorPayload['_metadata'],
|
|
16
|
-
): never {
|
|
17
|
-
const payload: AppErrorPayload = {
|
|
18
|
-
code,
|
|
19
|
-
message: message || getErrorMessage(code),
|
|
20
|
-
details,
|
|
21
|
-
validationErrors,
|
|
22
|
-
_metadata: {
|
|
23
|
-
timestamp: new Date().toISOString(),
|
|
24
|
-
...metadata,
|
|
25
|
-
},
|
|
26
|
-
}
|
|
27
|
-
throw new ConvexError<AppErrorPayload>(payload)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Throw UNAUTHENTICATED error (401).
|
|
32
|
-
* Use when user is not authenticated.
|
|
33
|
-
*/
|
|
34
|
-
export function unauthenticated(
|
|
35
|
-
message?: string,
|
|
36
|
-
details?: Record<string, Value>,
|
|
37
|
-
): never {
|
|
38
|
-
throwAppError('UNAUTHENTICATED', message, details)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Throw FORBIDDEN error (403).
|
|
43
|
-
* Use when user lacks permission for the action.
|
|
44
|
-
*/
|
|
45
|
-
export function forbidden(
|
|
46
|
-
message?: string,
|
|
47
|
-
details?: Record<string, Value>,
|
|
48
|
-
): never {
|
|
49
|
-
throwAppError('FORBIDDEN', message, details)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Throw NOT_FOUND error (404).
|
|
54
|
-
* Use when a requested resource doesn't exist.
|
|
55
|
-
*/
|
|
56
|
-
export function notFound(
|
|
57
|
-
message?: string,
|
|
58
|
-
details?: Record<string, Value>,
|
|
59
|
-
): never {
|
|
60
|
-
throwAppError('NOT_FOUND', message, details)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Throw BAD_REQUEST error (400).
|
|
65
|
-
* Use for invalid input or business rule violations.
|
|
66
|
-
*/
|
|
67
|
-
export function badRequest(
|
|
68
|
-
message?: string,
|
|
69
|
-
details?: Record<string, Value>,
|
|
70
|
-
): never {
|
|
71
|
-
throwAppError('BAD_REQUEST', message, details)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Throw CONFLICT error (409).
|
|
76
|
-
* Use for state conflicts (e.g., optimistic concurrency control failures).
|
|
77
|
-
*/
|
|
78
|
-
export function conflict(
|
|
79
|
-
message?: string,
|
|
80
|
-
details?: Record<string, Value>,
|
|
81
|
-
): never {
|
|
82
|
-
throwAppError('CONFLICT', message, details)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Throw INTERNAL error (500).
|
|
87
|
-
* Use for internal server errors and unexpected conditions.
|
|
88
|
-
*/
|
|
89
|
-
export function internal(
|
|
90
|
-
message?: string,
|
|
91
|
-
details?: Record<string, Value>,
|
|
92
|
-
): never {
|
|
93
|
-
throwAppError('INTERNAL', message, details)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Throw FEATURE_DISABLED error.
|
|
98
|
-
* Use when a feature flag is off.
|
|
99
|
-
*/
|
|
100
|
-
export function featureDisabled(
|
|
101
|
-
message?: string,
|
|
102
|
-
details?: Record<string, Value>,
|
|
103
|
-
): never {
|
|
104
|
-
throwAppError('FEATURE_DISABLED', message, details)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Throw RATE_LIMITED error (429).
|
|
109
|
-
* Use when rate limits are exceeded.
|
|
110
|
-
*/
|
|
111
|
-
export function rateLimited(
|
|
112
|
-
message?: string,
|
|
113
|
-
details?: Record<string, Value>,
|
|
114
|
-
): never {
|
|
115
|
-
throwAppError('RATE_LIMITED', message, details)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Throw VALIDATION_ERROR (422).
|
|
120
|
-
* Use for form validation errors with field-level details.
|
|
121
|
-
*
|
|
122
|
-
* @example
|
|
123
|
-
* ```ts
|
|
124
|
-
* const errors: ValidationError[] = []
|
|
125
|
-
* if (!email.includes('@')) {
|
|
126
|
-
* errors.push({ field: 'email', message: 'Invalid email address' })
|
|
127
|
-
* }
|
|
128
|
-
* if (errors.length > 0) {
|
|
129
|
-
* validationError(errors, 'Please check your input')
|
|
130
|
-
* }
|
|
131
|
-
* ```
|
|
132
|
-
*/
|
|
133
|
-
export function validationError(
|
|
134
|
-
validationErrors: ValidationError[],
|
|
135
|
-
message?: string,
|
|
136
|
-
details?: Record<string, Value>,
|
|
137
|
-
): never {
|
|
138
|
-
throwAppError('VALIDATION_ERROR', message, details, validationErrors)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Create error helpers pre-enriched with metadata.
|
|
143
|
-
*
|
|
144
|
-
* @example
|
|
145
|
-
* ```ts
|
|
146
|
-
* const err = withErrorMeta({
|
|
147
|
-
* functionName: 'users.update',
|
|
148
|
-
* requestId: 'abc123',
|
|
149
|
-
* })
|
|
150
|
-
* err.notFound('User not found')
|
|
151
|
-
* ```
|
|
152
|
-
*/
|
|
153
|
-
export function withErrorMeta(meta: {
|
|
154
|
-
functionName?: string
|
|
155
|
-
requestId?: string
|
|
156
|
-
userId?: string
|
|
157
|
-
}) {
|
|
158
|
-
const mergeDetails = (d?: Record<string, Value>): Record<string, Value> => ({
|
|
159
|
-
...(d ?? {}),
|
|
160
|
-
...meta,
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
return {
|
|
164
|
-
unauthenticated: (m?: string, d?: Record<string, Value>) =>
|
|
165
|
-
unauthenticated(m, mergeDetails(d)),
|
|
166
|
-
forbidden: (m?: string, d?: Record<string, Value>) =>
|
|
167
|
-
forbidden(m, mergeDetails(d)),
|
|
168
|
-
notFound: (m?: string, d?: Record<string, Value>) =>
|
|
169
|
-
notFound(m, mergeDetails(d)),
|
|
170
|
-
badRequest: (m?: string, d?: Record<string, Value>) =>
|
|
171
|
-
badRequest(m, mergeDetails(d)),
|
|
172
|
-
conflict: (m?: string, d?: Record<string, Value>) =>
|
|
173
|
-
conflict(m, mergeDetails(d)),
|
|
174
|
-
internal: (m?: string, d?: Record<string, Value>) =>
|
|
175
|
-
internal(m, mergeDetails(d)),
|
|
176
|
-
validationError: (
|
|
177
|
-
ve: ValidationError[],
|
|
178
|
-
m?: string,
|
|
179
|
-
d?: Record<string, Value>,
|
|
180
|
-
) => validationError(ve, m, mergeDetails(d)),
|
|
181
|
-
rateLimited: (m?: string, d?: Record<string, Value>) =>
|
|
182
|
-
rateLimited(m, mergeDetails(d)),
|
|
183
|
-
}
|
|
184
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
// @geenius-tools/convex-errors — src/types.ts
|
|
2
|
-
|
|
3
|
-
import type { Value } from 'convex/values'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Standard error codes for Convex applications.
|
|
7
|
-
*/
|
|
8
|
-
export type AppErrorCode =
|
|
9
|
-
| 'UNAUTHENTICATED'
|
|
10
|
-
| 'FORBIDDEN'
|
|
11
|
-
| 'NOT_FOUND'
|
|
12
|
-
| 'BAD_REQUEST'
|
|
13
|
-
| 'CONFLICT'
|
|
14
|
-
| 'INTERNAL'
|
|
15
|
-
| 'VALIDATION_ERROR'
|
|
16
|
-
| 'RATE_LIMITED'
|
|
17
|
-
| 'FEATURE_DISABLED'
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* A field-level validation error.
|
|
21
|
-
*/
|
|
22
|
-
export type ValidationError = {
|
|
23
|
-
field: string
|
|
24
|
-
message: string
|
|
25
|
-
code?: string
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Structured payload thrown via `ConvexError<AppErrorPayload>`.
|
|
30
|
-
*/
|
|
31
|
-
export type AppErrorPayload = {
|
|
32
|
-
code: AppErrorCode
|
|
33
|
-
message?: string
|
|
34
|
-
details?: Record<string, Value>
|
|
35
|
-
validationErrors?: ValidationError[]
|
|
36
|
-
_metadata?: {
|
|
37
|
-
timestamp: string
|
|
38
|
-
functionName?: string
|
|
39
|
-
userId?: string
|
|
40
|
-
requestId?: string
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* HTTP status code mapping for error codes.
|
|
46
|
-
*/
|
|
47
|
-
export const HTTP_STATUS_MAP: Record<AppErrorCode, number> = {
|
|
48
|
-
UNAUTHENTICATED: 401,
|
|
49
|
-
FORBIDDEN: 403,
|
|
50
|
-
NOT_FOUND: 404,
|
|
51
|
-
BAD_REQUEST: 400,
|
|
52
|
-
CONFLICT: 409,
|
|
53
|
-
INTERNAL: 500,
|
|
54
|
-
VALIDATION_ERROR: 422,
|
|
55
|
-
RATE_LIMITED: 429,
|
|
56
|
-
FEATURE_DISABLED: 403,
|
|
57
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
// @geenius-tools/convex-wrappers — src/utils.ts
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Generate a unique request ID for tracing.
|
|
5
|
-
*/
|
|
6
|
-
export function makeRequestId(): string {
|
|
7
|
-
const timestamp = Date.now().toString(36)
|
|
8
|
-
const random = Math.random().toString(36).substring(2, 8)
|
|
9
|
-
return `req_${timestamp}_${random}`
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Redact sensitive fields from an object for logging.
|
|
14
|
-
*/
|
|
15
|
-
export function redactForLogging(
|
|
16
|
-
args: Record<string, unknown>,
|
|
17
|
-
config: { sensitiveFields?: string[] },
|
|
18
|
-
): Record<string, unknown> {
|
|
19
|
-
const sensitiveFields = new Set(
|
|
20
|
-
config.sensitiveFields ?? ['password', 'token', 'secret', 'apiKey', 'accessToken'],
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
const result: Record<string, unknown> = {}
|
|
24
|
-
for (const [key, value] of Object.entries(args)) {
|
|
25
|
-
if (sensitiveFields.has(key)) {
|
|
26
|
-
result[key] = '[REDACTED]'
|
|
27
|
-
} else {
|
|
28
|
-
result[key] = value
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return result
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Extract userId from args (for trusted internal calls).
|
|
36
|
-
* Throws if userId is missing.
|
|
37
|
-
*/
|
|
38
|
-
export function extractRequiredUserId(
|
|
39
|
-
args: Record<string, unknown>,
|
|
40
|
-
context: string,
|
|
41
|
-
): string {
|
|
42
|
-
const userId = args.userId
|
|
43
|
-
if (!userId || typeof userId !== 'string') {
|
|
44
|
-
throw new Error(`Missing userId in ${context}`)
|
|
45
|
-
}
|
|
46
|
-
return userId
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Extract optional userId from args.
|
|
51
|
-
*/
|
|
52
|
-
export function extractOptionalUserId(
|
|
53
|
-
args: Record<string, unknown>,
|
|
54
|
-
): string | undefined {
|
|
55
|
-
const userId = args.userId
|
|
56
|
-
if (!userId || typeof userId !== 'string') return undefined
|
|
57
|
-
return userId
|
|
58
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"moduleResolution": "bundler",
|
|
6
|
-
"lib": [
|
|
7
|
-
"ES2022"
|
|
8
|
-
],
|
|
9
|
-
"strict": true,
|
|
10
|
-
"esModuleInterop": true,
|
|
11
|
-
"skipLibCheck": true,
|
|
12
|
-
"forceConsistentCasingInFileNames": true,
|
|
13
|
-
"resolveJsonModule": true,
|
|
14
|
-
"isolatedModules": true,
|
|
15
|
-
"declaration": true,
|
|
16
|
-
"declarationMap": true,
|
|
17
|
-
"sourceMap": true,
|
|
18
|
-
"outDir": "./dist",
|
|
19
|
-
"rootDir": "./src"
|
|
20
|
-
},
|
|
21
|
-
"include": [
|
|
22
|
-
"src"
|
|
23
|
-
],
|
|
24
|
-
"exclude": [
|
|
25
|
-
"node_modules",
|
|
26
|
-
"dist"
|
|
27
|
-
]
|
|
28
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@geenius-tools/devtools",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"description": "Development tooling utilities for Geenius projects",
|
|
6
|
-
"main": "./dist/index.js",
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"import": "./dist/index.js",
|
|
11
|
-
"types": "./dist/index.d.ts"
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"scripts": {
|
|
15
|
-
"build": "tsup",
|
|
16
|
-
"type-check": "tsc --noEmit",
|
|
17
|
-
"clean": "rm -rf dist .turbo"
|
|
18
|
-
},
|
|
19
|
-
"devDependencies": {
|
|
20
|
-
"typescript": "~6.0.2",
|
|
21
|
-
"tsup": "^8.0.1"
|
|
22
|
-
},
|
|
23
|
-
"publishConfig": {
|
|
24
|
-
"access": "public"
|
|
25
|
-
},
|
|
26
|
-
"license": "MIT"
|
|
27
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@geenius-tools/devtools-react",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"private": false,
|
|
5
|
-
"type": "module",
|
|
6
|
-
"description": "React dev-tools UI — floating toolbar, performance panel, inspector, GitHub issues",
|
|
7
|
-
"license": "MIT",
|
|
8
|
-
"publishConfig": {
|
|
9
|
-
"access": "public"
|
|
10
|
-
},
|
|
11
|
-
"main": "./dist/index.js",
|
|
12
|
-
"module": "./dist/index.js",
|
|
13
|
-
"types": "./dist/index.d.ts",
|
|
14
|
-
"exports": {
|
|
15
|
-
".": {
|
|
16
|
-
"types": "./dist/index.d.ts",
|
|
17
|
-
"import": "./dist/index.js"
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
"files": [
|
|
21
|
-
"dist",
|
|
22
|
-
"src"
|
|
23
|
-
],
|
|
24
|
-
"scripts": {
|
|
25
|
-
"build": "tsup",
|
|
26
|
-
"clean": "rm -rf dist",
|
|
27
|
-
"type-check": "tsc --noEmit",
|
|
28
|
-
"prepublishOnly": "pnpm clean && pnpm build"
|
|
29
|
-
},
|
|
30
|
-
"dependencies": {
|
|
31
|
-
"@geenius-tools/logger": "workspace:*"
|
|
32
|
-
},
|
|
33
|
-
"devDependencies": {
|
|
34
|
-
"@geenius-ui/react": "workspace:*",
|
|
35
|
-
"@types/react": "^19.0.0",
|
|
36
|
-
"@types/react-dom": "^19.0.0",
|
|
37
|
-
"lucide-react": "^0.577.0",
|
|
38
|
-
"react": "^19.2.4",
|
|
39
|
-
"react-dom": "^19.2.4",
|
|
40
|
-
"tsup": "^8.5.1",
|
|
41
|
-
"typescript": "~5.9.3"
|
|
42
|
-
},
|
|
43
|
-
"peerDependencies": {
|
|
44
|
-
"@geenius-ui/react": "workspace:*",
|
|
45
|
-
"lucide-react": ">=0.300.0",
|
|
46
|
-
"react": "^18.0.0 || ^19.0.0",
|
|
47
|
-
"react-dom": "^18.0.0 || ^19.0.0"
|
|
48
|
-
},
|
|
49
|
-
"author": "Antigravity HQ",
|
|
50
|
-
"engines": {
|
|
51
|
-
"node": ">=20.0.0"
|
|
52
|
-
}
|
|
53
|
-
}
|