nobalmako 1.0.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.
Files changed (123) hide show
  1. package/README.md +112 -0
  2. package/components.json +22 -0
  3. package/dist/nobalmako.js +272 -0
  4. package/drizzle/0000_pink_spiral.sql +126 -0
  5. package/drizzle/meta/0000_snapshot.json +1027 -0
  6. package/drizzle/meta/_journal.json +13 -0
  7. package/drizzle.config.ts +10 -0
  8. package/eslint.config.mjs +18 -0
  9. package/next.config.ts +7 -0
  10. package/package.json +80 -0
  11. package/postcss.config.mjs +7 -0
  12. package/public/file.svg +1 -0
  13. package/public/globe.svg +1 -0
  14. package/public/next.svg +1 -0
  15. package/public/vercel.svg +1 -0
  16. package/public/window.svg +1 -0
  17. package/server/index.ts +118 -0
  18. package/src/app/api/api-keys/[id]/route.ts +147 -0
  19. package/src/app/api/api-keys/route.ts +151 -0
  20. package/src/app/api/audit-logs/route.ts +84 -0
  21. package/src/app/api/auth/forgot-password/route.ts +47 -0
  22. package/src/app/api/auth/login/route.ts +99 -0
  23. package/src/app/api/auth/logout/route.ts +15 -0
  24. package/src/app/api/auth/me/route.ts +23 -0
  25. package/src/app/api/auth/mfa/setup/route.ts +33 -0
  26. package/src/app/api/auth/mfa/verify/route.ts +45 -0
  27. package/src/app/api/auth/register/route.ts +140 -0
  28. package/src/app/api/auth/reset-password/route.ts +52 -0
  29. package/src/app/api/auth/update/route.ts +71 -0
  30. package/src/app/api/auth/verify/route.ts +39 -0
  31. package/src/app/api/environments/route.ts +227 -0
  32. package/src/app/api/team-members/route.ts +385 -0
  33. package/src/app/api/teams/route.ts +217 -0
  34. package/src/app/api/variable-history/route.ts +218 -0
  35. package/src/app/api/variables/route.ts +476 -0
  36. package/src/app/api/webhooks/route.ts +77 -0
  37. package/src/app/api-keys/APIKeysClient.tsx +316 -0
  38. package/src/app/api-keys/page.tsx +10 -0
  39. package/src/app/api-reference/page.tsx +324 -0
  40. package/src/app/audit-log/AuditLogClient.tsx +229 -0
  41. package/src/app/audit-log/page.tsx +10 -0
  42. package/src/app/auth/forgot-password/page.tsx +121 -0
  43. package/src/app/auth/login/LoginForm.tsx +145 -0
  44. package/src/app/auth/login/page.tsx +11 -0
  45. package/src/app/auth/register/RegisterForm.tsx +156 -0
  46. package/src/app/auth/register/page.tsx +16 -0
  47. package/src/app/auth/reset-password/page.tsx +160 -0
  48. package/src/app/dashboard/DashboardClient.tsx +219 -0
  49. package/src/app/dashboard/page.tsx +11 -0
  50. package/src/app/docs/page.tsx +251 -0
  51. package/src/app/favicon.ico +0 -0
  52. package/src/app/globals.css +123 -0
  53. package/src/app/layout.tsx +35 -0
  54. package/src/app/page.tsx +231 -0
  55. package/src/app/profile/ProfileClient.tsx +230 -0
  56. package/src/app/profile/page.tsx +10 -0
  57. package/src/app/project/[id]/ProjectDetailsClient.tsx +512 -0
  58. package/src/app/project/[id]/page.tsx +17 -0
  59. package/src/bin/nobalmako.ts +341 -0
  60. package/src/components/ApiKeysManager.tsx +529 -0
  61. package/src/components/AppLayout.tsx +193 -0
  62. package/src/components/BulkActions.tsx +138 -0
  63. package/src/components/CreateEnvironmentDialog.tsx +207 -0
  64. package/src/components/CreateTeamDialog.tsx +174 -0
  65. package/src/components/CreateVariableDialog.tsx +311 -0
  66. package/src/components/DeleteEnvironmentDialog.tsx +104 -0
  67. package/src/components/DeleteTeamDialog.tsx +112 -0
  68. package/src/components/DeleteVariableDialog.tsx +103 -0
  69. package/src/components/EditEnvironmentDialog.tsx +202 -0
  70. package/src/components/EditMemberDialog.tsx +143 -0
  71. package/src/components/EditTeamDialog.tsx +178 -0
  72. package/src/components/EditVariableDialog.tsx +231 -0
  73. package/src/components/ImportVariablesDialog.tsx +347 -0
  74. package/src/components/InviteMemberDialog.tsx +191 -0
  75. package/src/components/LeaveProjectDialog.tsx +111 -0
  76. package/src/components/MFASettings.tsx +136 -0
  77. package/src/components/ProjectDiff.tsx +123 -0
  78. package/src/components/Providers.tsx +24 -0
  79. package/src/components/RemoveMemberDialog.tsx +112 -0
  80. package/src/components/SearchDialog.tsx +276 -0
  81. package/src/components/SecurityOverview.tsx +92 -0
  82. package/src/components/TeamMembersManager.tsx +103 -0
  83. package/src/components/VariableHistoryDialog.tsx +265 -0
  84. package/src/components/WebhooksManager.tsx +169 -0
  85. package/src/components/ui/alert-dialog.tsx +160 -0
  86. package/src/components/ui/alert.tsx +59 -0
  87. package/src/components/ui/avatar.tsx +53 -0
  88. package/src/components/ui/badge.tsx +46 -0
  89. package/src/components/ui/button.tsx +62 -0
  90. package/src/components/ui/card.tsx +92 -0
  91. package/src/components/ui/checkbox.tsx +32 -0
  92. package/src/components/ui/dialog.tsx +143 -0
  93. package/src/components/ui/dropdown-menu.tsx +257 -0
  94. package/src/components/ui/input.tsx +21 -0
  95. package/src/components/ui/label.tsx +24 -0
  96. package/src/components/ui/select.tsx +190 -0
  97. package/src/components/ui/separator.tsx +28 -0
  98. package/src/components/ui/sonner.tsx +37 -0
  99. package/src/components/ui/switch.tsx +31 -0
  100. package/src/components/ui/table.tsx +117 -0
  101. package/src/components/ui/tabs.tsx +66 -0
  102. package/src/components/ui/textarea.tsx +18 -0
  103. package/src/hooks/use-api-keys.ts +95 -0
  104. package/src/hooks/use-audit-logs.ts +58 -0
  105. package/src/hooks/use-auth.tsx +121 -0
  106. package/src/hooks/use-environments.ts +33 -0
  107. package/src/hooks/use-project-permissions.ts +49 -0
  108. package/src/hooks/use-team-members.ts +30 -0
  109. package/src/hooks/use-teams.ts +33 -0
  110. package/src/hooks/use-variables.ts +38 -0
  111. package/src/lib/audit.ts +36 -0
  112. package/src/lib/auth.ts +108 -0
  113. package/src/lib/crypto.ts +39 -0
  114. package/src/lib/db.ts +15 -0
  115. package/src/lib/dynamic-providers.ts +19 -0
  116. package/src/lib/email.ts +110 -0
  117. package/src/lib/mail.ts +51 -0
  118. package/src/lib/permissions.ts +51 -0
  119. package/src/lib/schema.ts +240 -0
  120. package/src/lib/seed.ts +107 -0
  121. package/src/lib/utils.ts +6 -0
  122. package/src/lib/webhooks.ts +42 -0
  123. package/tsconfig.json +34 -0
@@ -0,0 +1,107 @@
1
+ import 'dotenv/config'
2
+ import { db } from './db'
3
+ import { users, teams, environments, environmentVariables, teamMembers } from './schema'
4
+ import bcrypt from 'bcryptjs'
5
+ import { encrypt } from './crypto'
6
+
7
+ async function seed() {
8
+ console.log('🌱 Seeding database...')
9
+
10
+ try {
11
+ // Clear existing data in correct order
12
+ console.log('Cleaning up existing data...')
13
+ await db.delete(teamMembers)
14
+ await db.delete(environmentVariables)
15
+ await db.delete(environments)
16
+ await db.delete(teams)
17
+ await db.delete(users)
18
+
19
+ // Create users
20
+ const hashedPassword = await bcrypt.hash('password123', 10)
21
+
22
+ console.log('Creating users...')
23
+ const [ownerUser] = await db.insert(users).values({
24
+ email: 'owner@nobalmako.com',
25
+ name: 'Owner User',
26
+ password: hashedPassword,
27
+ }).returning()
28
+
29
+ const [adminUser] = await db.insert(users).values({
30
+ email: 'admin@nobalmako.com',
31
+ name: 'Admin User',
32
+ password: hashedPassword,
33
+ }).returning()
34
+
35
+ const [devUser] = await db.insert(users).values({
36
+ email: 'dev@nobalmako.com',
37
+ name: 'Developer User',
38
+ password: hashedPassword,
39
+ }).returning()
40
+
41
+ const [viewerUser] = await db.insert(users).values({
42
+ email: 'viewer@nobalmako.com',
43
+ name: 'Viewer User',
44
+ password: hashedPassword,
45
+ }).returning()
46
+
47
+ // Create a demo project (team)
48
+ console.log('Creating project...')
49
+ const [project] = await db.insert(teams).values({
50
+ name: 'SecureApp V1',
51
+ description: 'Main production application for the company.',
52
+ ownerId: ownerUser.id,
53
+ }).returning()
54
+
55
+ // Assign team members with different roles
56
+ console.log('Assigning roles...')
57
+ await db.insert(teamMembers).values([
58
+ { teamId: project.id, userId: adminUser.id, role: 'admin' },
59
+ { teamId: project.id, userId: devUser.id, role: 'developer' },
60
+ { teamId: project.id, userId: viewerUser.id, role: 'viewer' },
61
+ { teamId: project.id, userId: ownerUser.id, role: 'owner' },
62
+ ])
63
+
64
+ // Create environments
65
+ console.log('Creating environments...')
66
+ const [prodEnv] = await db.insert(environments).values({
67
+ name: 'Production',
68
+ teamId: project.id,
69
+ isDefault: true,
70
+ color: '#ef4444' // Red for prod
71
+ }).returning()
72
+
73
+ const [stagingEnv] = await db.insert(environments).values({
74
+ name: 'Staging',
75
+ teamId: project.id,
76
+ color: '#f59e0b' // Amber for staging
77
+ }).returning()
78
+
79
+ // Add some variables
80
+ console.log('Adding environment variables...')
81
+ const variables = [
82
+ { key: 'DATABASE_URL', value: 'postgresql://prod-db.example.com/app', environmentId: prodEnv.id },
83
+ { key: 'API_KEY', value: 'sk_prod_51Hj6l8V2', environmentId: prodEnv.id },
84
+ { key: 'DATABASE_URL', value: 'postgresql://staging-db.example.com/app', environmentId: stagingEnv.id },
85
+ { key: 'API_KEY', value: 'sk_test_90Kl2mP1', environmentId: stagingEnv.id },
86
+ ]
87
+
88
+ for (const v of variables) {
89
+ await db.insert(environmentVariables).values({
90
+ key: v.key,
91
+ value: encrypt(v.value),
92
+ environmentId: v.environmentId,
93
+ teamId: project.id,
94
+ createdBy: ownerUser.id,
95
+ })
96
+ }
97
+
98
+ console.log('✅ Seed successful!')
99
+ console.log('Admin Email: admin@nobalmako.com')
100
+ console.log('Password: password123')
101
+ } catch (error) {
102
+ console.error('❌ Seed failed:', error)
103
+ process.exit(1)
104
+ }
105
+ }
106
+
107
+ seed()
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
@@ -0,0 +1,42 @@
1
+ import { db } from '@/lib/db';
2
+ import { webhooks } from '@/lib/schema';
3
+ import { eq } from 'drizzle-orm';
4
+ import crypto from 'crypto';
5
+
6
+ export async function triggerWebhook(teamId: string, event: string, payload: any) {
7
+ try {
8
+ const results = await db.select().from(webhooks).where(eq(webhooks.teamId, teamId));
9
+
10
+ for (const hook of results) {
11
+ if (!hook.events?.includes(event)) continue;
12
+
13
+ const body = JSON.stringify({
14
+ event,
15
+ timestamp: new Date().toISOString(),
16
+ data: payload
17
+ });
18
+
19
+ const headers: Record<string, string> = {
20
+ 'Content-Type': 'application/json',
21
+ 'User-Agent': 'Nobalmako-Webhook/1.0',
22
+ };
23
+
24
+ if (hook.secret) {
25
+ const signature = crypto
26
+ .createHmac('sha256', hook.secret)
27
+ .update(body)
28
+ .digest('hex');
29
+ headers['X-Nobalmako-Signature'] = signature;
30
+ }
31
+
32
+ // Fire and forget (don't await to avoid slowing down main API response)
33
+ fetch(hook.url, {
34
+ method: 'POST',
35
+ headers,
36
+ body,
37
+ }).catch(err => console.error(`Webhook failed for ${hook.url}:`, err));
38
+ }
39
+ } catch (error) {
40
+ console.error('Error triggering webhooks:', error);
41
+ }
42
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "react-jsx",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./src/*"]
23
+ }
24
+ },
25
+ "include": [
26
+ "next-env.d.ts",
27
+ "**/*.ts",
28
+ "**/*.tsx",
29
+ ".next/types/**/*.ts",
30
+ ".next/dev/types/**/*.ts",
31
+ "**/*.mts"
32
+ ],
33
+ "exclude": ["node_modules", "server"]
34
+ }