@nordsym/apiclaw 1.0.0 → 1.1.1

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 (161) hide show
  1. package/AGENTS.md +74 -0
  2. package/HEARTBEAT.md +4 -0
  3. package/IDENTITY.md +22 -0
  4. package/README.md +193 -202
  5. package/SOUL.md +36 -0
  6. package/STATUS.md +237 -0
  7. package/TOOLS.md +36 -0
  8. package/USER.md +17 -0
  9. package/{backend/convex → convex}/_generated/api.d.ts +12 -6
  10. package/convex/analytics.ts +90 -0
  11. package/convex/credits.ts +211 -0
  12. package/convex/http.ts +578 -0
  13. package/convex/providers.ts +516 -0
  14. package/convex/purchases.ts +183 -0
  15. package/convex/ratelimit.ts +104 -0
  16. package/convex/schema.ts +220 -0
  17. package/convex/telemetry.ts +81 -0
  18. package/convex.json +3 -0
  19. package/dist/credentials.d.ts +19 -0
  20. package/dist/credentials.d.ts.map +1 -0
  21. package/dist/credentials.js +158 -0
  22. package/dist/credentials.js.map +1 -0
  23. package/dist/credits.d.ts +14 -11
  24. package/dist/credits.d.ts.map +1 -1
  25. package/dist/credits.js +151 -99
  26. package/dist/credits.js.map +1 -1
  27. package/dist/discovery.d.ts +7 -16
  28. package/dist/discovery.d.ts.map +1 -1
  29. package/dist/discovery.js +33 -40
  30. package/dist/discovery.js.map +1 -1
  31. package/dist/execute.d.ts +19 -0
  32. package/dist/execute.d.ts.map +1 -0
  33. package/dist/execute.js +285 -0
  34. package/dist/execute.js.map +1 -0
  35. package/dist/index.js +175 -31
  36. package/dist/index.js.map +1 -1
  37. package/dist/proxy.d.ts +6 -0
  38. package/dist/proxy.d.ts.map +1 -0
  39. package/dist/proxy.js +19 -0
  40. package/dist/proxy.js.map +1 -0
  41. package/dist/registry/apis.json +95362 -202
  42. package/dist/registry/apis_expanded.json +100853 -0
  43. package/dist/stripe.d.ts +68 -0
  44. package/dist/stripe.d.ts.map +1 -0
  45. package/dist/stripe.js +196 -0
  46. package/dist/stripe.js.map +1 -0
  47. package/dist/telemetry.d.ts +28 -0
  48. package/dist/telemetry.d.ts.map +1 -0
  49. package/dist/telemetry.js +50 -0
  50. package/dist/telemetry.js.map +1 -0
  51. package/dist/test.d.ts +3 -2
  52. package/dist/test.d.ts.map +1 -1
  53. package/dist/test.js +105 -75
  54. package/dist/test.js.map +1 -1
  55. package/dist/types.d.ts +0 -28
  56. package/dist/types.d.ts.map +1 -1
  57. package/dist/webhook.d.ts +2 -0
  58. package/dist/webhook.d.ts.map +1 -0
  59. package/dist/webhook.js +90 -0
  60. package/dist/webhook.js.map +1 -0
  61. package/landing/DESIGN.md +343 -0
  62. package/landing/package-lock.json +1196 -7
  63. package/landing/package.json +5 -1
  64. package/landing/public/android-chrome-192x192.png +0 -0
  65. package/landing/public/android-chrome-512x512.png +0 -0
  66. package/landing/public/apple-touch-icon.png +0 -0
  67. package/landing/public/demo.gif +0 -0
  68. package/landing/public/demo.mp4 +0 -0
  69. package/landing/public/favicon-16x16.png +0 -0
  70. package/landing/public/favicon-32x32.png +0 -0
  71. package/landing/public/favicon.ico +0 -0
  72. package/landing/public/favicon.svg +3 -0
  73. package/landing/public/icon.svg +47 -0
  74. package/landing/public/logo-mono.svg +37 -0
  75. package/landing/public/logo-simple.svg +45 -0
  76. package/landing/public/logo.svg +84 -0
  77. package/landing/public/og-template.html +184 -0
  78. package/landing/public/site.webmanifest +31 -0
  79. package/landing/scripts/generate-assets.js +284 -0
  80. package/landing/scripts/generate-pngs.js +48 -0
  81. package/landing/scripts/generate-stats.js +42 -0
  82. package/landing/src/app/admin/page.tsx +348 -0
  83. package/landing/src/app/api/auth/magic-link/route.ts +73 -0
  84. package/landing/src/app/api/auth/session/route.ts +38 -0
  85. package/landing/src/app/api/auth/verify/route.ts +43 -0
  86. package/landing/src/app/api/og/route.tsx +84 -0
  87. package/landing/src/app/globals.css +439 -100
  88. package/landing/src/app/layout.tsx +37 -7
  89. package/landing/src/app/page.tsx +627 -552
  90. package/landing/src/app/providers/dashboard/login/page.tsx +176 -0
  91. package/landing/src/app/providers/dashboard/page.tsx +589 -0
  92. package/landing/src/app/providers/dashboard/verify/page.tsx +106 -0
  93. package/landing/src/app/providers/layout.tsx +14 -0
  94. package/landing/src/app/providers/page.tsx +402 -0
  95. package/landing/src/app/providers/register/page.tsx +670 -0
  96. package/landing/src/components/ProviderDashboard.tsx +794 -0
  97. package/landing/src/hooks/useDashboardData.ts +99 -0
  98. package/landing/src/lib/apis.json +116054 -0
  99. package/landing/src/lib/convex-client.ts +106 -0
  100. package/landing/src/lib/mock-data.ts +285 -0
  101. package/landing/src/lib/stats.json +6 -0
  102. package/landing/tailwind.config.ts +12 -11
  103. package/landing/tsconfig.tsbuildinfo +1 -0
  104. package/package.json +21 -20
  105. package/scripts/SYMBOT-FIX.md +238 -0
  106. package/scripts/demo-simulation.py +177 -0
  107. package/scripts/expand-more.py +502 -0
  108. package/scripts/expand-registry.py +434 -0
  109. package/scripts/history-sanitizer.ts +272 -0
  110. package/scripts/mass-scrape.py +1308 -0
  111. package/scripts/sync-and-deploy.sh +36 -0
  112. package/src/credentials.ts +177 -0
  113. package/src/credits.ts +190 -122
  114. package/src/discovery.ts +45 -58
  115. package/src/execute.ts +350 -0
  116. package/src/index.ts +184 -32
  117. package/src/proxy.ts +24 -0
  118. package/src/registry/apis.json +95362 -202
  119. package/src/registry/apis_expanded.json +100853 -0
  120. package/src/stripe.ts +243 -0
  121. package/src/telemetry.ts +71 -0
  122. package/src/test.ts +127 -89
  123. package/src/types.ts +0 -34
  124. package/src/webhook.ts +107 -0
  125. package/.github/ISSUE_TEMPLATE/add-api.yml +0 -123
  126. package/BRIEFING.md +0 -30
  127. package/backend/convex/apiKeys.ts +0 -75
  128. package/backend/convex/purchases.ts +0 -74
  129. package/backend/convex/schema.ts +0 -45
  130. package/backend/convex/transactions.ts +0 -57
  131. package/backend/convex/users.ts +0 -94
  132. package/backend/package-lock.json +0 -521
  133. package/backend/package.json +0 -15
  134. package/dist/registry/parse_apis.py +0 -146
  135. package/dist/revenuecat.d.ts +0 -61
  136. package/dist/revenuecat.d.ts.map +0 -1
  137. package/dist/revenuecat.js +0 -166
  138. package/dist/revenuecat.js.map +0 -1
  139. package/dist/webhooks/revenuecat.d.ts +0 -48
  140. package/dist/webhooks/revenuecat.d.ts.map +0 -1
  141. package/dist/webhooks/revenuecat.js +0 -119
  142. package/dist/webhooks/revenuecat.js.map +0 -1
  143. package/docs/revenuecat-setup.md +0 -89
  144. package/landing/src/app/api/keys/route.ts +0 -71
  145. package/landing/src/app/api/log/route.ts +0 -37
  146. package/landing/src/app/api/stats/route.ts +0 -37
  147. package/landing/src/app/page.tsx.bak +0 -567
  148. package/landing/src/components/AddKeyModal.tsx +0 -159
  149. package/newsletter-template.html +0 -71
  150. package/outreach/OUTREACH-SYSTEM.md +0 -211
  151. package/outreach/email-template.html +0 -179
  152. package/outreach/targets.md +0 -133
  153. package/src/registry/parse_apis.py +0 -146
  154. package/src/revenuecat.ts +0 -239
  155. package/src/webhooks/revenuecat.ts +0 -187
  156. /package/{backend/convex → convex}/README.md +0 -0
  157. /package/{backend/convex → convex}/_generated/api.js +0 -0
  158. /package/{backend/convex → convex}/_generated/dataModel.d.ts +0 -0
  159. /package/{backend/convex → convex}/_generated/server.d.ts +0 -0
  160. /package/{backend/convex → convex}/_generated/server.js +0 -0
  161. /package/{backend/convex → convex}/tsconfig.json +0 -0
@@ -0,0 +1,176 @@
1
+ "use client";
2
+
3
+ import { useState, useEffect } from "react";
4
+ import { Mail, Loader2, Check, ArrowRight, Sun, Moon } from "lucide-react";
5
+ import Link from "next/link";
6
+ import { useRouter } from "next/navigation";
7
+
8
+ export default function LoginPage() {
9
+ const router = useRouter();
10
+ const [isDark, setIsDark] = useState(false);
11
+ const [email, setEmail] = useState("");
12
+ const [isLoading, setIsLoading] = useState(false);
13
+ const [isSent, setIsSent] = useState(false);
14
+ const [error, setError] = useState<string | null>(null);
15
+
16
+ useEffect(() => {
17
+ // Check if already logged in
18
+ const sessionToken = localStorage.getItem("apiclaw_session");
19
+ if (sessionToken) {
20
+ router.push("/providers/dashboard");
21
+ return;
22
+ }
23
+
24
+ const saved = localStorage.getItem("theme");
25
+ const prefersDark = saved ? saved === "dark" : true;
26
+ setIsDark(prefersDark);
27
+ document.documentElement.classList.toggle("dark", prefersDark);
28
+ }, [router]);
29
+
30
+ const toggleTheme = () => {
31
+ const newTheme = !isDark;
32
+ setIsDark(newTheme);
33
+ document.documentElement.classList.toggle("dark", newTheme);
34
+ localStorage.setItem("theme", newTheme ? "dark" : "light");
35
+ };
36
+
37
+ const handleSubmit = async (e: React.FormEvent) => {
38
+ e.preventDefault();
39
+ setIsLoading(true);
40
+ setError(null);
41
+
42
+ try {
43
+ const response = await fetch("/api/auth/magic-link", {
44
+ method: "POST",
45
+ headers: { "Content-Type": "application/json" },
46
+ body: JSON.stringify({ email }),
47
+ });
48
+
49
+ if (!response.ok) {
50
+ const data = await response.json();
51
+ throw new Error(data.error || "Failed to send magic link");
52
+ }
53
+
54
+ setIsSent(true);
55
+ } catch (err) {
56
+ setError(err instanceof Error ? err.message : "Something went wrong");
57
+ } finally {
58
+ setIsLoading(false);
59
+ }
60
+ };
61
+
62
+ if (isSent) {
63
+ return (
64
+ <main className="min-h-screen flex items-center justify-center px-6">
65
+ <div className="max-w-md w-full text-center">
66
+ <div className="w-20 h-20 rounded-full bg-accent/20 flex items-center justify-center mx-auto mb-8">
67
+ <Check className="w-10 h-10 text-accent" />
68
+ </div>
69
+ <h1 className="text-3xl font-bold mb-4">Check Your Email</h1>
70
+ <p className="text-text-secondary mb-2">
71
+ We&apos;ve sent a magic link to:
72
+ </p>
73
+ <p className="font-semibold text-lg mb-8">{email}</p>
74
+ <p className="text-sm text-text-muted">
75
+ Click the link in the email to sign in. The link expires in 15 minutes.
76
+ </p>
77
+ <button
78
+ onClick={() => setIsSent(false)}
79
+ className="mt-8 text-accent hover:underline"
80
+ >
81
+ Use a different email
82
+ </button>
83
+ </div>
84
+ </main>
85
+ );
86
+ }
87
+
88
+ return (
89
+ <main className="min-h-screen">
90
+ {/* Header */}
91
+ <header className="fixed top-0 w-full z-50 bg-background/90 backdrop-blur-xl border-b border-border-subtle">
92
+ <div className="max-w-6xl mx-auto px-6 py-4 flex items-center justify-between">
93
+ <Link href="/" className="flex items-center gap-3">
94
+ <div className="w-9 h-9 rounded-xl bg-accent/20 flex items-center justify-center text-xl">
95
+ 🦞
96
+ </div>
97
+ <span className="font-bold text-lg tracking-tight">APIClaw</span>
98
+ </Link>
99
+ <button
100
+ onClick={toggleTheme}
101
+ className="p-2 rounded-lg hover:bg-[var(--surface)] transition"
102
+ aria-label="Toggle theme"
103
+ >
104
+ {isDark ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
105
+ </button>
106
+ </div>
107
+ </header>
108
+
109
+ <div className="pt-32 pb-24 px-6">
110
+ <div className="max-w-md mx-auto">
111
+ <div className="text-center mb-8">
112
+ <h1 className="text-3xl font-bold mb-2">Provider Dashboard</h1>
113
+ <p className="text-text-secondary">
114
+ Sign in to manage your APIs and view analytics
115
+ </p>
116
+ </div>
117
+
118
+ <div className="rounded-2xl bg-surface-elevated border border-border p-8">
119
+ <form onSubmit={handleSubmit} className="space-y-6">
120
+ <div>
121
+ <label className="block text-sm font-medium mb-2">Email</label>
122
+ <div className="relative">
123
+ <Mail className="absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 text-text-muted" />
124
+ <input
125
+ type="email"
126
+ value={email}
127
+ onChange={(e) => {
128
+ setEmail(e.target.value);
129
+ setError(null);
130
+ }}
131
+ placeholder="you@company.com"
132
+ required
133
+ className="w-full pl-12 pr-4 py-3 rounded-xl bg-surface border border-border focus:border-accent focus:outline-none transition"
134
+ />
135
+ </div>
136
+ </div>
137
+
138
+ {error && (
139
+ <div className="p-3 rounded-lg bg-red-500/10 border border-red-500/30 text-red-500 text-sm">
140
+ {error}
141
+ </div>
142
+ )}
143
+
144
+ <button
145
+ type="submit"
146
+ disabled={isLoading || !email}
147
+ className="btn-primary w-full justify-center disabled:opacity-50"
148
+ >
149
+ {isLoading ? (
150
+ <>
151
+ <Loader2 className="w-5 h-5 animate-spin" />
152
+ Sending...
153
+ </>
154
+ ) : (
155
+ <>
156
+ Send Magic Link
157
+ <ArrowRight className="w-5 h-5" />
158
+ </>
159
+ )}
160
+ </button>
161
+ </form>
162
+
163
+ <div className="mt-6 pt-6 border-t border-border text-center">
164
+ <p className="text-sm text-text-muted">
165
+ Don&apos;t have APIs listed?{" "}
166
+ <Link href="/providers/register" className="text-accent hover:underline">
167
+ Register as a provider
168
+ </Link>
169
+ </p>
170
+ </div>
171
+ </div>
172
+ </div>
173
+ </div>
174
+ </main>
175
+ );
176
+ }