@adityanair98/api-oracle 0.5.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/LICENSE +21 -0
- package/README.md +216 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.js +74 -0
- package/dist/dashboard/public/app.js +1004 -0
- package/dist/dashboard/public/index.html +142 -0
- package/dist/dashboard/public/public/app.js +1004 -0
- package/dist/dashboard/public/public/index.html +142 -0
- package/dist/dashboard/public/public/styles.css +1464 -0
- package/dist/dashboard/public/styles.css +1464 -0
- package/dist/dashboard/routes/api.d.ts +7 -0
- package/dist/dashboard/routes/api.js +245 -0
- package/dist/dashboard/server.d.ts +9 -0
- package/dist/dashboard/server.js +45 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +23 -0
- package/dist/knowledge/db.d.ts +22 -0
- package/dist/knowledge/db.js +182 -0
- package/dist/knowledge/schema.d.ts +275 -0
- package/dist/knowledge/schema.js +135 -0
- package/dist/knowledge/scorer.d.ts +63 -0
- package/dist/knowledge/scorer.js +314 -0
- package/dist/knowledge/search.d.ts +37 -0
- package/dist/knowledge/search.js +111 -0
- package/dist/knowledge/synonyms.d.ts +36 -0
- package/dist/knowledge/synonyms.js +523 -0
- package/dist/knowledge/tfidf.d.ts +42 -0
- package/dist/knowledge/tfidf.js +138 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.js +40 -0
- package/dist/tools/check-freshness.d.ts +9 -0
- package/dist/tools/check-freshness.js +95 -0
- package/dist/tools/compare-apis.d.ts +8 -0
- package/dist/tools/compare-apis.js +149 -0
- package/dist/tools/find-api.d.ts +9 -0
- package/dist/tools/find-api.js +120 -0
- package/dist/tools/get-setup-guide.d.ts +8 -0
- package/dist/tools/get-setup-guide.js +127 -0
- package/dist/updater/linter.d.ts +31 -0
- package/dist/updater/linter.js +219 -0
- package/dist/updater/report.d.ts +29 -0
- package/dist/updater/report.js +96 -0
- package/dist/updater/staleness.d.ts +39 -0
- package/dist/updater/staleness.js +66 -0
- package/dist/updater/version-tracker.d.ts +28 -0
- package/dist/updater/version-tracker.js +50 -0
- package/dist/utils/config.d.ts +11 -0
- package/dist/utils/config.js +13 -0
- package/dist/utils/logger.d.ts +20 -0
- package/dist/utils/logger.js +32 -0
- package/package.json +56 -0
- package/src/entries/ai/anthropic.json +95 -0
- package/src/entries/ai/eleven-labs.json +90 -0
- package/src/entries/ai/openai.json +95 -0
- package/src/entries/ai/replicate.json +87 -0
- package/src/entries/ai/resemble-ai.json +88 -0
- package/src/entries/ai/stability-ai.json +89 -0
- package/src/entries/analytics/posthog.json +88 -0
- package/src/entries/analytics/sentry.json +84 -0
- package/src/entries/auth/auth0.json +90 -0
- package/src/entries/auth/clerk.json +95 -0
- package/src/entries/cms/contentful.json +92 -0
- package/src/entries/cms/sanity.json +92 -0
- package/src/entries/cms/strapi.json +93 -0
- package/src/entries/commerce/medusa.json +91 -0
- package/src/entries/commerce/shopify-api.json +91 -0
- package/src/entries/communication/sendbird.json +85 -0
- package/src/entries/communication/stream-chat.json +94 -0
- package/src/entries/database/firebase.json +88 -0
- package/src/entries/database/neon.json +94 -0
- package/src/entries/database/planetscale.json +95 -0
- package/src/entries/database/supabase.json +94 -0
- package/src/entries/database/upstash.json +94 -0
- package/src/entries/devops/fly-io.json +90 -0
- package/src/entries/devops/netlify.json +90 -0
- package/src/entries/devops/railway.json +90 -0
- package/src/entries/devops/vercel.json +90 -0
- package/src/entries/email/mailgun.json +91 -0
- package/src/entries/email/postmark.json +91 -0
- package/src/entries/email/resend.json +89 -0
- package/src/entries/email/sendgrid.json +90 -0
- package/src/entries/forms/formspark.json +85 -0
- package/src/entries/forms/typeform.json +98 -0
- package/src/entries/infrastructure/aws-s3.json +104 -0
- package/src/entries/infrastructure/cloudflare-r2.json +92 -0
- package/src/entries/infrastructure/cloudflare-workers.json +92 -0
- package/src/entries/infrastructure/digital-ocean-spaces.json +87 -0
- package/src/entries/integration/nango.json +90 -0
- package/src/entries/integration/zapier.json +92 -0
- package/src/entries/maps/google-maps.json +89 -0
- package/src/entries/maps/mapbox.json +87 -0
- package/src/entries/media/deepgram.json +84 -0
- package/src/entries/media/imgix.json +84 -0
- package/src/entries/media/mux.json +94 -0
- package/src/entries/messaging/ably.json +94 -0
- package/src/entries/messaging/pusher.json +94 -0
- package/src/entries/messaging/twilio.json +94 -0
- package/src/entries/messaging/vonage.json +89 -0
- package/src/entries/notifications/knock.json +84 -0
- package/src/entries/notifications/novu.json +84 -0
- package/src/entries/notifications/onesignal.json +84 -0
- package/src/entries/payments/lemonsqueezy.json +91 -0
- package/src/entries/payments/paddle.json +90 -0
- package/src/entries/payments/paypal.json +91 -0
- package/src/entries/payments/razorpay.json +85 -0
- package/src/entries/payments/square.json +91 -0
- package/src/entries/payments/stripe.json +96 -0
- package/src/entries/scheduling/cal-com.json +90 -0
- package/src/entries/scheduling/calendly.json +90 -0
- package/src/entries/search/algolia.json +96 -0
- package/src/entries/security/arcjet.json +89 -0
- package/src/entries/security/snyk.json +90 -0
- package/src/entries/storage/cloudinary.json +93 -0
- package/src/entries/storage/uploadthing.json +90 -0
- package/src/entries/testing/browserstack.json +86 -0
- package/src/entries/testing/checkly.json +89 -0
- package/src/entries/workflow/inngest.json +88 -0
- package/src/entries/workflow/temporal.json +90 -0
- package/src/entries/workflow/trigger-dev.json +89 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schemas and TypeScript types for API knowledge base entries.
|
|
3
|
+
* This is the central contract — all data must conform to this schema.
|
|
4
|
+
*
|
|
5
|
+
* Exports: ApiEntrySchema, ApiEntry, PartialApiEntrySchema, validateEntry
|
|
6
|
+
*/
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
declare const UseCaseSchema: z.ZodObject<{
|
|
9
|
+
task: z.ZodString;
|
|
10
|
+
fit: z.ZodEnum<{
|
|
11
|
+
perfect: "perfect";
|
|
12
|
+
good: "good";
|
|
13
|
+
partial: "partial";
|
|
14
|
+
}>;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
declare const AuthSchema: z.ZodObject<{
|
|
17
|
+
method: z.ZodEnum<{
|
|
18
|
+
api_key: "api_key";
|
|
19
|
+
oauth2: "oauth2";
|
|
20
|
+
bearer_token: "bearer_token";
|
|
21
|
+
basic_auth: "basic_auth";
|
|
22
|
+
none: "none";
|
|
23
|
+
}>;
|
|
24
|
+
setupSteps: z.ZodArray<z.ZodString>;
|
|
25
|
+
envVarName: z.ZodString;
|
|
26
|
+
codeSnippet: z.ZodString;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
declare const PricingSchema: z.ZodObject<{
|
|
29
|
+
model: z.ZodEnum<{
|
|
30
|
+
free: "free";
|
|
31
|
+
freemium: "freemium";
|
|
32
|
+
paid: "paid";
|
|
33
|
+
usage_based: "usage_based";
|
|
34
|
+
open_source: "open_source";
|
|
35
|
+
}>;
|
|
36
|
+
freeTier: z.ZodNullable<z.ZodString>;
|
|
37
|
+
startingPrice: z.ZodNullable<z.ZodString>;
|
|
38
|
+
costPer: z.ZodNullable<z.ZodString>;
|
|
39
|
+
pricingUrl: z.ZodString;
|
|
40
|
+
}, z.core.$strip>;
|
|
41
|
+
declare const RateLimitsSchema: z.ZodObject<{
|
|
42
|
+
tier: z.ZodString;
|
|
43
|
+
limit: z.ZodString;
|
|
44
|
+
notes: z.ZodString;
|
|
45
|
+
retryStrategy: z.ZodString;
|
|
46
|
+
}, z.core.$strip>;
|
|
47
|
+
declare const SdkSchema: z.ZodObject<{
|
|
48
|
+
primaryLanguage: z.ZodString;
|
|
49
|
+
installCommand: z.ZodString;
|
|
50
|
+
importStatement: z.ZodString;
|
|
51
|
+
otherLanguages: z.ZodArray<z.ZodString>;
|
|
52
|
+
}, z.core.$strip>;
|
|
53
|
+
declare const CodeExampleSchema: z.ZodObject<{
|
|
54
|
+
title: z.ZodString;
|
|
55
|
+
language: z.ZodString;
|
|
56
|
+
code: z.ZodString;
|
|
57
|
+
notes: z.ZodString;
|
|
58
|
+
}, z.core.$strip>;
|
|
59
|
+
declare const ReliabilitySchema: z.ZodObject<{
|
|
60
|
+
uptimeGuarantee: z.ZodNullable<z.ZodString>;
|
|
61
|
+
statusPageUrl: z.ZodNullable<z.ZodString>;
|
|
62
|
+
notes: z.ZodString;
|
|
63
|
+
}, z.core.$strip>;
|
|
64
|
+
export declare const ApiEntrySchema: z.ZodObject<{
|
|
65
|
+
name: z.ZodString;
|
|
66
|
+
slug: z.ZodString;
|
|
67
|
+
category: z.ZodEnum<{
|
|
68
|
+
auth: "auth";
|
|
69
|
+
email: "email";
|
|
70
|
+
payments: "payments";
|
|
71
|
+
ai: "ai";
|
|
72
|
+
storage: "storage";
|
|
73
|
+
search: "search";
|
|
74
|
+
messaging: "messaging";
|
|
75
|
+
analytics: "analytics";
|
|
76
|
+
database: "database";
|
|
77
|
+
media: "media";
|
|
78
|
+
notifications: "notifications";
|
|
79
|
+
maps: "maps";
|
|
80
|
+
communication: "communication";
|
|
81
|
+
devops: "devops";
|
|
82
|
+
infrastructure: "infrastructure";
|
|
83
|
+
commerce: "commerce";
|
|
84
|
+
cms: "cms";
|
|
85
|
+
forms: "forms";
|
|
86
|
+
scheduling: "scheduling";
|
|
87
|
+
testing: "testing";
|
|
88
|
+
security: "security";
|
|
89
|
+
workflow: "workflow";
|
|
90
|
+
integration: "integration";
|
|
91
|
+
}>;
|
|
92
|
+
subcategory: z.ZodString;
|
|
93
|
+
website: z.ZodString;
|
|
94
|
+
description: z.ZodString;
|
|
95
|
+
useCases: z.ZodArray<z.ZodObject<{
|
|
96
|
+
task: z.ZodString;
|
|
97
|
+
fit: z.ZodEnum<{
|
|
98
|
+
perfect: "perfect";
|
|
99
|
+
good: "good";
|
|
100
|
+
partial: "partial";
|
|
101
|
+
}>;
|
|
102
|
+
}, z.core.$strip>>;
|
|
103
|
+
auth: z.ZodObject<{
|
|
104
|
+
method: z.ZodEnum<{
|
|
105
|
+
api_key: "api_key";
|
|
106
|
+
oauth2: "oauth2";
|
|
107
|
+
bearer_token: "bearer_token";
|
|
108
|
+
basic_auth: "basic_auth";
|
|
109
|
+
none: "none";
|
|
110
|
+
}>;
|
|
111
|
+
setupSteps: z.ZodArray<z.ZodString>;
|
|
112
|
+
envVarName: z.ZodString;
|
|
113
|
+
codeSnippet: z.ZodString;
|
|
114
|
+
}, z.core.$strip>;
|
|
115
|
+
pricing: z.ZodObject<{
|
|
116
|
+
model: z.ZodEnum<{
|
|
117
|
+
free: "free";
|
|
118
|
+
freemium: "freemium";
|
|
119
|
+
paid: "paid";
|
|
120
|
+
usage_based: "usage_based";
|
|
121
|
+
open_source: "open_source";
|
|
122
|
+
}>;
|
|
123
|
+
freeTier: z.ZodNullable<z.ZodString>;
|
|
124
|
+
startingPrice: z.ZodNullable<z.ZodString>;
|
|
125
|
+
costPer: z.ZodNullable<z.ZodString>;
|
|
126
|
+
pricingUrl: z.ZodString;
|
|
127
|
+
}, z.core.$strip>;
|
|
128
|
+
rateLimits: z.ZodObject<{
|
|
129
|
+
tier: z.ZodString;
|
|
130
|
+
limit: z.ZodString;
|
|
131
|
+
notes: z.ZodString;
|
|
132
|
+
retryStrategy: z.ZodString;
|
|
133
|
+
}, z.core.$strip>;
|
|
134
|
+
sdk: z.ZodObject<{
|
|
135
|
+
primaryLanguage: z.ZodString;
|
|
136
|
+
installCommand: z.ZodString;
|
|
137
|
+
importStatement: z.ZodString;
|
|
138
|
+
otherLanguages: z.ZodArray<z.ZodString>;
|
|
139
|
+
}, z.core.$strip>;
|
|
140
|
+
codeExamples: z.ZodArray<z.ZodObject<{
|
|
141
|
+
title: z.ZodString;
|
|
142
|
+
language: z.ZodString;
|
|
143
|
+
code: z.ZodString;
|
|
144
|
+
notes: z.ZodString;
|
|
145
|
+
}, z.core.$strip>>;
|
|
146
|
+
gotchas: z.ZodArray<z.ZodString>;
|
|
147
|
+
reliability: z.ZodObject<{
|
|
148
|
+
uptimeGuarantee: z.ZodNullable<z.ZodString>;
|
|
149
|
+
statusPageUrl: z.ZodNullable<z.ZodString>;
|
|
150
|
+
notes: z.ZodString;
|
|
151
|
+
}, z.core.$strip>;
|
|
152
|
+
qualityScore: z.ZodNumber;
|
|
153
|
+
qualityJustification: z.ZodString;
|
|
154
|
+
alternatives: z.ZodArray<z.ZodString>;
|
|
155
|
+
complementary: z.ZodArray<z.ZodString>;
|
|
156
|
+
bestFor: z.ZodString;
|
|
157
|
+
lastVerified: z.ZodString;
|
|
158
|
+
entryVersion: z.ZodNumber;
|
|
159
|
+
addedBy: z.ZodString;
|
|
160
|
+
}, z.core.$strip>;
|
|
161
|
+
export declare const PartialApiEntrySchema: z.ZodObject<{
|
|
162
|
+
name: z.ZodOptional<z.ZodString>;
|
|
163
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
164
|
+
category: z.ZodOptional<z.ZodEnum<{
|
|
165
|
+
auth: "auth";
|
|
166
|
+
email: "email";
|
|
167
|
+
payments: "payments";
|
|
168
|
+
ai: "ai";
|
|
169
|
+
storage: "storage";
|
|
170
|
+
search: "search";
|
|
171
|
+
messaging: "messaging";
|
|
172
|
+
analytics: "analytics";
|
|
173
|
+
database: "database";
|
|
174
|
+
media: "media";
|
|
175
|
+
notifications: "notifications";
|
|
176
|
+
maps: "maps";
|
|
177
|
+
communication: "communication";
|
|
178
|
+
devops: "devops";
|
|
179
|
+
infrastructure: "infrastructure";
|
|
180
|
+
commerce: "commerce";
|
|
181
|
+
cms: "cms";
|
|
182
|
+
forms: "forms";
|
|
183
|
+
scheduling: "scheduling";
|
|
184
|
+
testing: "testing";
|
|
185
|
+
security: "security";
|
|
186
|
+
workflow: "workflow";
|
|
187
|
+
integration: "integration";
|
|
188
|
+
}>>;
|
|
189
|
+
subcategory: z.ZodOptional<z.ZodString>;
|
|
190
|
+
website: z.ZodOptional<z.ZodString>;
|
|
191
|
+
description: z.ZodOptional<z.ZodString>;
|
|
192
|
+
useCases: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
193
|
+
task: z.ZodString;
|
|
194
|
+
fit: z.ZodEnum<{
|
|
195
|
+
perfect: "perfect";
|
|
196
|
+
good: "good";
|
|
197
|
+
partial: "partial";
|
|
198
|
+
}>;
|
|
199
|
+
}, z.core.$strip>>>;
|
|
200
|
+
auth: z.ZodOptional<z.ZodObject<{
|
|
201
|
+
method: z.ZodEnum<{
|
|
202
|
+
api_key: "api_key";
|
|
203
|
+
oauth2: "oauth2";
|
|
204
|
+
bearer_token: "bearer_token";
|
|
205
|
+
basic_auth: "basic_auth";
|
|
206
|
+
none: "none";
|
|
207
|
+
}>;
|
|
208
|
+
setupSteps: z.ZodArray<z.ZodString>;
|
|
209
|
+
envVarName: z.ZodString;
|
|
210
|
+
codeSnippet: z.ZodString;
|
|
211
|
+
}, z.core.$strip>>;
|
|
212
|
+
pricing: z.ZodOptional<z.ZodObject<{
|
|
213
|
+
model: z.ZodEnum<{
|
|
214
|
+
free: "free";
|
|
215
|
+
freemium: "freemium";
|
|
216
|
+
paid: "paid";
|
|
217
|
+
usage_based: "usage_based";
|
|
218
|
+
open_source: "open_source";
|
|
219
|
+
}>;
|
|
220
|
+
freeTier: z.ZodNullable<z.ZodString>;
|
|
221
|
+
startingPrice: z.ZodNullable<z.ZodString>;
|
|
222
|
+
costPer: z.ZodNullable<z.ZodString>;
|
|
223
|
+
pricingUrl: z.ZodString;
|
|
224
|
+
}, z.core.$strip>>;
|
|
225
|
+
rateLimits: z.ZodOptional<z.ZodObject<{
|
|
226
|
+
tier: z.ZodString;
|
|
227
|
+
limit: z.ZodString;
|
|
228
|
+
notes: z.ZodString;
|
|
229
|
+
retryStrategy: z.ZodString;
|
|
230
|
+
}, z.core.$strip>>;
|
|
231
|
+
sdk: z.ZodOptional<z.ZodObject<{
|
|
232
|
+
primaryLanguage: z.ZodString;
|
|
233
|
+
installCommand: z.ZodString;
|
|
234
|
+
importStatement: z.ZodString;
|
|
235
|
+
otherLanguages: z.ZodArray<z.ZodString>;
|
|
236
|
+
}, z.core.$strip>>;
|
|
237
|
+
codeExamples: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
238
|
+
title: z.ZodString;
|
|
239
|
+
language: z.ZodString;
|
|
240
|
+
code: z.ZodString;
|
|
241
|
+
notes: z.ZodString;
|
|
242
|
+
}, z.core.$strip>>>;
|
|
243
|
+
gotchas: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
244
|
+
reliability: z.ZodOptional<z.ZodObject<{
|
|
245
|
+
uptimeGuarantee: z.ZodNullable<z.ZodString>;
|
|
246
|
+
statusPageUrl: z.ZodNullable<z.ZodString>;
|
|
247
|
+
notes: z.ZodString;
|
|
248
|
+
}, z.core.$strip>>;
|
|
249
|
+
qualityScore: z.ZodOptional<z.ZodNumber>;
|
|
250
|
+
qualityJustification: z.ZodOptional<z.ZodString>;
|
|
251
|
+
alternatives: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
252
|
+
complementary: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
253
|
+
bestFor: z.ZodOptional<z.ZodString>;
|
|
254
|
+
lastVerified: z.ZodOptional<z.ZodString>;
|
|
255
|
+
entryVersion: z.ZodOptional<z.ZodNumber>;
|
|
256
|
+
addedBy: z.ZodOptional<z.ZodString>;
|
|
257
|
+
}, z.core.$strip>;
|
|
258
|
+
export type ApiEntry = z.infer<typeof ApiEntrySchema>;
|
|
259
|
+
export type PartialApiEntry = z.infer<typeof PartialApiEntrySchema>;
|
|
260
|
+
export type UseCase = z.infer<typeof UseCaseSchema>;
|
|
261
|
+
export type Auth = z.infer<typeof AuthSchema>;
|
|
262
|
+
export type Pricing = z.infer<typeof PricingSchema>;
|
|
263
|
+
export type RateLimits = z.infer<typeof RateLimitsSchema>;
|
|
264
|
+
export type Sdk = z.infer<typeof SdkSchema>;
|
|
265
|
+
export type CodeExample = z.infer<typeof CodeExampleSchema>;
|
|
266
|
+
export type Reliability = z.infer<typeof ReliabilitySchema>;
|
|
267
|
+
export type Category = ApiEntry["category"];
|
|
268
|
+
export declare function validateEntry(data: unknown): {
|
|
269
|
+
success: true;
|
|
270
|
+
data: ApiEntry;
|
|
271
|
+
} | {
|
|
272
|
+
success: false;
|
|
273
|
+
errors: string[];
|
|
274
|
+
};
|
|
275
|
+
export {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schemas and TypeScript types for API knowledge base entries.
|
|
3
|
+
* This is the central contract — all data must conform to this schema.
|
|
4
|
+
*
|
|
5
|
+
* Exports: ApiEntrySchema, ApiEntry, PartialApiEntrySchema, validateEntry
|
|
6
|
+
*/
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
// ─── Sub-schemas ─────────────────────────────────────────────────────────────
|
|
9
|
+
const UseCaseSchema = z.object({
|
|
10
|
+
task: z.string().min(1, "Use case task cannot be empty"),
|
|
11
|
+
fit: z.enum(["perfect", "good", "partial"]),
|
|
12
|
+
});
|
|
13
|
+
const AuthSchema = z.object({
|
|
14
|
+
method: z.enum(["api_key", "oauth2", "bearer_token", "basic_auth", "none"]),
|
|
15
|
+
setupSteps: z.array(z.string().min(1)).min(1, "At least one setup step required"),
|
|
16
|
+
envVarName: z.string().min(1, "Environment variable name required"),
|
|
17
|
+
codeSnippet: z.string().min(1, "Auth code snippet required"),
|
|
18
|
+
});
|
|
19
|
+
const PricingSchema = z.object({
|
|
20
|
+
model: z.enum(["free", "freemium", "paid", "usage_based", "open_source"]),
|
|
21
|
+
freeTier: z.string().nullable(),
|
|
22
|
+
startingPrice: z.string().nullable(),
|
|
23
|
+
costPer: z.string().nullable(),
|
|
24
|
+
pricingUrl: z.string().url("Pricing URL must be a valid URL"),
|
|
25
|
+
});
|
|
26
|
+
const RateLimitsSchema = z.object({
|
|
27
|
+
tier: z.string().min(1),
|
|
28
|
+
limit: z.string().min(1),
|
|
29
|
+
notes: z.string().min(1),
|
|
30
|
+
retryStrategy: z.string().min(1),
|
|
31
|
+
});
|
|
32
|
+
const SdkSchema = z.object({
|
|
33
|
+
primaryLanguage: z.string().min(1),
|
|
34
|
+
installCommand: z.string().min(1),
|
|
35
|
+
importStatement: z.string().min(1),
|
|
36
|
+
otherLanguages: z.array(z.string()),
|
|
37
|
+
});
|
|
38
|
+
const CodeExampleSchema = z.object({
|
|
39
|
+
title: z.string().min(1, "Code example title required"),
|
|
40
|
+
language: z.string().min(1),
|
|
41
|
+
code: z.string().min(1, "Code example cannot be empty"),
|
|
42
|
+
notes: z.string(),
|
|
43
|
+
});
|
|
44
|
+
const ReliabilitySchema = z.object({
|
|
45
|
+
uptimeGuarantee: z.string().nullable(),
|
|
46
|
+
statusPageUrl: z.string().url("Status page URL must be valid").nullable(),
|
|
47
|
+
notes: z.string(),
|
|
48
|
+
});
|
|
49
|
+
// ─── Main Schema ──────────────────────────────────────────────────────────────
|
|
50
|
+
export const ApiEntrySchema = z.object({
|
|
51
|
+
// IDENTITY
|
|
52
|
+
name: z.string().min(1, "API name required"),
|
|
53
|
+
slug: z
|
|
54
|
+
.string()
|
|
55
|
+
.min(1, "Slug required")
|
|
56
|
+
.regex(/^[a-z0-9-]+$/, "Slug must be lowercase kebab-case"),
|
|
57
|
+
category: z.enum([
|
|
58
|
+
"email",
|
|
59
|
+
"payments",
|
|
60
|
+
"ai",
|
|
61
|
+
"storage",
|
|
62
|
+
"search",
|
|
63
|
+
"auth",
|
|
64
|
+
"messaging",
|
|
65
|
+
"analytics",
|
|
66
|
+
"database",
|
|
67
|
+
"media",
|
|
68
|
+
"notifications",
|
|
69
|
+
"maps",
|
|
70
|
+
"communication",
|
|
71
|
+
// Session 4 additions
|
|
72
|
+
"devops",
|
|
73
|
+
"infrastructure",
|
|
74
|
+
"commerce",
|
|
75
|
+
"cms",
|
|
76
|
+
"forms",
|
|
77
|
+
"scheduling",
|
|
78
|
+
"testing",
|
|
79
|
+
"security",
|
|
80
|
+
"workflow",
|
|
81
|
+
"integration",
|
|
82
|
+
]),
|
|
83
|
+
subcategory: z.string().min(1, "Subcategory required"),
|
|
84
|
+
website: z.string().url("Website must be a valid URL"),
|
|
85
|
+
description: z.string().min(20, "Description must be at least 20 characters"),
|
|
86
|
+
// USE CASES
|
|
87
|
+
useCases: z
|
|
88
|
+
.array(UseCaseSchema)
|
|
89
|
+
.min(1, "At least one use case required"),
|
|
90
|
+
// AUTHENTICATION
|
|
91
|
+
auth: AuthSchema,
|
|
92
|
+
// PRICING
|
|
93
|
+
pricing: PricingSchema,
|
|
94
|
+
// RATE LIMITS
|
|
95
|
+
rateLimits: RateLimitsSchema,
|
|
96
|
+
// SDK & INTEGRATION
|
|
97
|
+
sdk: SdkSchema,
|
|
98
|
+
// CODE EXAMPLES
|
|
99
|
+
codeExamples: z
|
|
100
|
+
.array(CodeExampleSchema)
|
|
101
|
+
.min(1, "At least one code example required"),
|
|
102
|
+
// GOTCHAS
|
|
103
|
+
gotchas: z
|
|
104
|
+
.array(z.string().min(1))
|
|
105
|
+
.min(2, "At least 2 gotchas required"),
|
|
106
|
+
// RELIABILITY
|
|
107
|
+
reliability: ReliabilitySchema,
|
|
108
|
+
// SCORING
|
|
109
|
+
qualityScore: z
|
|
110
|
+
.number()
|
|
111
|
+
.min(1, "Quality score minimum is 1")
|
|
112
|
+
.max(10, "Quality score maximum is 10"),
|
|
113
|
+
qualityJustification: z.string().min(10, "Quality justification required"),
|
|
114
|
+
// RELATIONSHIPS
|
|
115
|
+
alternatives: z.array(z.string()),
|
|
116
|
+
complementary: z.array(z.string()),
|
|
117
|
+
bestFor: z.string().min(1, "bestFor summary required"),
|
|
118
|
+
// METADATA
|
|
119
|
+
lastVerified: z
|
|
120
|
+
.string()
|
|
121
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, "lastVerified must be ISO date (YYYY-MM-DD)"),
|
|
122
|
+
entryVersion: z.number().int().min(1, "Entry version must be at least 1"),
|
|
123
|
+
addedBy: z.string().min(1, "addedBy required"),
|
|
124
|
+
});
|
|
125
|
+
// ─── Partial Schema (for filtering/search params) ─────────────────────────────
|
|
126
|
+
export const PartialApiEntrySchema = ApiEntrySchema.partial();
|
|
127
|
+
// ─── Validation Helper ────────────────────────────────────────────────────────
|
|
128
|
+
export function validateEntry(data) {
|
|
129
|
+
const result = ApiEntrySchema.safeParse(data);
|
|
130
|
+
if (result.success) {
|
|
131
|
+
return { success: true, data: result.data };
|
|
132
|
+
}
|
|
133
|
+
const errors = result.error.issues.map((issue) => `${issue.path.join(".")} — ${issue.message}`);
|
|
134
|
+
return { success: false, errors };
|
|
135
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scoring/ranking engine — ranks API entries by relevance to a task description.
|
|
3
|
+
* Uses weighted multi-factor scoring across 6 dimensions.
|
|
4
|
+
*
|
|
5
|
+
* Exports: SCORING_WEIGHTS, DEFAULT_WEIGHTS, ScoreWeights, scoreEntry, rankEntries,
|
|
6
|
+
* tokenize, scoreUseCaseFit, scoreDevExperience
|
|
7
|
+
*/
|
|
8
|
+
import type { ApiEntry } from "./schema.js";
|
|
9
|
+
import type { SearchConstraints, RankedResult } from "./search.js";
|
|
10
|
+
export interface ScoreWeights {
|
|
11
|
+
useCaseFit: number;
|
|
12
|
+
qualityScore: number;
|
|
13
|
+
developerExperience: number;
|
|
14
|
+
pricingFit: number;
|
|
15
|
+
keywordRelevance: number;
|
|
16
|
+
recencyBonus: number;
|
|
17
|
+
}
|
|
18
|
+
/** Default weights — must sum to exactly 1.0 */
|
|
19
|
+
export declare const SCORING_WEIGHTS: ScoreWeights;
|
|
20
|
+
/** Alias for backwards compatibility */
|
|
21
|
+
export declare const DEFAULT_WEIGHTS: ScoreWeights;
|
|
22
|
+
/**
|
|
23
|
+
* Normalize text to a set of lowercase tokens.
|
|
24
|
+
* Allows 2-char tokens (important for "ai", "db", "ml", "go").
|
|
25
|
+
*/
|
|
26
|
+
export declare function tokenize(text: string): Set<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Score against multiple fields with weighted relevance:
|
|
29
|
+
* - Use case tasks (40%) — with fit multiplier, best match wins
|
|
30
|
+
* - bestFor (25%) — concise purpose statement
|
|
31
|
+
* - Description (20%) — first 200 chars (signal-dense)
|
|
32
|
+
* - Category signals (15%) — broad category alignment
|
|
33
|
+
*/
|
|
34
|
+
export declare function scoreUseCaseFit(entry: ApiEntry, queryTokens: Set<string>): number;
|
|
35
|
+
/**
|
|
36
|
+
* DX sub-scoring with measurable, explicit factors:
|
|
37
|
+
* - TypeScript as primary SDK: 3 pts
|
|
38
|
+
* - 2+ code examples: 2 pts
|
|
39
|
+
* - envVarName defined (clear auth setup): 1 pt
|
|
40
|
+
* - Single npm install command: 1 pt
|
|
41
|
+
* - Multiple language SDKs (3+): 1 pt
|
|
42
|
+
* - Required language match: up to 2 pts (only when requiredLanguage is specified)
|
|
43
|
+
*
|
|
44
|
+
* Normalized to 0-1 range. Base max = 8 pts; with language constraint = 10 pts.
|
|
45
|
+
*/
|
|
46
|
+
export declare function scoreDevExperience(entry: ApiEntry, constraints?: SearchConstraints): number;
|
|
47
|
+
/**
|
|
48
|
+
* Compute a confidence value (0-1) for how certain we are about the top result.
|
|
49
|
+
*
|
|
50
|
+
* High confidence (>0.8): strong category match + high useCaseFit score
|
|
51
|
+
* Medium confidence (0.5-0.8): partial signals
|
|
52
|
+
* Low confidence (<0.5): weak query, no clear category
|
|
53
|
+
*/
|
|
54
|
+
export declare function computeConfidence(topResult: RankedResult, detectedCategory: string | null, detectedConfidence: number, allResults: RankedResult[]): number;
|
|
55
|
+
/** Human-readable confidence label */
|
|
56
|
+
export declare function confidenceLabel(confidence: number): "high" | "medium" | "low";
|
|
57
|
+
export interface ScoringContext {
|
|
58
|
+
expandedQuery: string;
|
|
59
|
+
detectedCategory: string | null;
|
|
60
|
+
detectedConfidence: number;
|
|
61
|
+
}
|
|
62
|
+
export declare function scoreEntry(entry: ApiEntry, query: string, constraints?: SearchConstraints, weights?: ScoreWeights, context?: ScoringContext): RankedResult;
|
|
63
|
+
export declare function rankEntries(entries: ApiEntry[], query: string, constraints?: SearchConstraints, topN?: number, weights?: ScoreWeights, context?: ScoringContext): RankedResult[];
|