@stackweld/registry 0.2.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/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-lint.log +436 -0
- package/.turbo/turbo-test.log +15 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/dist/__tests__/loader.test.d.ts +2 -0
- package/dist/__tests__/loader.test.d.ts.map +1 -0
- package/dist/__tests__/loader.test.js +126 -0
- package/dist/__tests__/loader.test.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/learning-resources.d.ts +16 -0
- package/dist/learning-resources.d.ts.map +1 -0
- package/dist/learning-resources.js +461 -0
- package/dist/learning-resources.js.map +1 -0
- package/dist/loader.d.ts +18 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +56 -0
- package/dist/loader.js.map +1 -0
- package/dist/schema.d.ts +147 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +79 -0
- package/dist/schema.js.map +1 -0
- package/package.json +39 -0
- package/src/__tests__/loader.test.ts +162 -0
- package/src/index.ts +4 -0
- package/src/learning-resources.ts +488 -0
- package/src/loader.ts +67 -0
- package/src/schema.ts +79 -0
- package/src/technologies/auth/clerk.yaml +29 -0
- package/src/technologies/auth/lucia.yaml +19 -0
- package/src/technologies/auth/nextauth.yaml +31 -0
- package/src/technologies/auth/supabase-auth.yaml +32 -0
- package/src/technologies/backend/django.yaml +17 -0
- package/src/technologies/backend/echo.yaml +17 -0
- package/src/technologies/backend/express.yaml +17 -0
- package/src/technologies/backend/fastapi.yaml +17 -0
- package/src/technologies/backend/fastify.yaml +17 -0
- package/src/technologies/backend/flask.yaml +17 -0
- package/src/technologies/backend/gin.yaml +17 -0
- package/src/technologies/backend/hono.yaml +17 -0
- package/src/technologies/backend/laravel.yaml +32 -0
- package/src/technologies/backend/nestjs.yaml +30 -0
- package/src/technologies/backend/spring-boot.yaml +30 -0
- package/src/technologies/backend/trpc.yaml +20 -0
- package/src/technologies/databases/kafka.yaml +27 -0
- package/src/technologies/databases/mariadb.yaml +30 -0
- package/src/technologies/databases/mongodb.yaml +25 -0
- package/src/technologies/databases/mysql.yaml +25 -0
- package/src/technologies/databases/neon.yaml +18 -0
- package/src/technologies/databases/pocketbase.yaml +24 -0
- package/src/technologies/databases/postgresql.yaml +26 -0
- package/src/technologies/databases/redis.yaml +23 -0
- package/src/technologies/databases/sqlite.yaml +19 -0
- package/src/technologies/databases/supabase.yaml +27 -0
- package/src/technologies/databases/turso.yaml +19 -0
- package/src/technologies/devops/biome.yaml +19 -0
- package/src/technologies/devops/cypress.yaml +20 -0
- package/src/technologies/devops/devcontainers.yaml +18 -0
- package/src/technologies/devops/docker.yaml +19 -0
- package/src/technologies/devops/eslint.yaml +18 -0
- package/src/technologies/devops/github-actions.yaml +18 -0
- package/src/technologies/devops/jest.yaml +19 -0
- package/src/technologies/devops/playwright.yaml +19 -0
- package/src/technologies/devops/pnpm.yaml +22 -0
- package/src/technologies/devops/prettier.yaml +19 -0
- package/src/technologies/devops/storybook.yaml +28 -0
- package/src/technologies/devops/turborepo.yaml +20 -0
- package/src/technologies/devops/typescript.yaml +20 -0
- package/src/technologies/devops/vitest.yaml +20 -0
- package/src/technologies/devops/zod.yaml +18 -0
- package/src/technologies/frontend/angular.yaml +19 -0
- package/src/technologies/frontend/astro.yaml +19 -0
- package/src/technologies/frontend/htmx.yaml +18 -0
- package/src/technologies/frontend/nextjs.yaml +22 -0
- package/src/technologies/frontend/nuxt.yaml +18 -0
- package/src/technologies/frontend/qwik.yaml +28 -0
- package/src/technologies/frontend/react.yaml +19 -0
- package/src/technologies/frontend/remix.yaml +28 -0
- package/src/technologies/frontend/solidjs.yaml +29 -0
- package/src/technologies/frontend/svelte.yaml +19 -0
- package/src/technologies/frontend/sveltekit.yaml +18 -0
- package/src/technologies/frontend/vue.yaml +18 -0
- package/src/technologies/orms/django-orm.yaml +21 -0
- package/src/technologies/orms/drizzle.yaml +23 -0
- package/src/technologies/orms/mongoose.yaml +22 -0
- package/src/technologies/orms/prisma.yaml +23 -0
- package/src/technologies/orms/sqlalchemy.yaml +21 -0
- package/src/technologies/orms/typeorm.yaml +21 -0
- package/src/technologies/runtimes/bun.yaml +24 -0
- package/src/technologies/runtimes/deno.yaml +30 -0
- package/src/technologies/runtimes/go.yaml +27 -0
- package/src/technologies/runtimes/nodejs.yaml +31 -0
- package/src/technologies/runtimes/php.yaml +30 -0
- package/src/technologies/runtimes/python.yaml +30 -0
- package/src/technologies/runtimes/rust.yaml +23 -0
- package/src/technologies/services/adminer.yaml +24 -0
- package/src/technologies/services/grafana.yaml +29 -0
- package/src/technologies/services/mailpit.yaml +27 -0
- package/src/technologies/services/minio.yaml +28 -0
- package/src/technologies/services/nginx.yaml +25 -0
- package/src/technologies/services/pgadmin.yaml +26 -0
- package/src/technologies/services/portainer.yaml +24 -0
- package/src/technologies/services/prometheus.yaml +27 -0
- package/src/technologies/services/rabbitmq.yaml +28 -0
- package/src/technologies/services/traefik.yaml +28 -0
- package/src/technologies/styling/chakra-ui.yaml +21 -0
- package/src/technologies/styling/css-modules.yaml +17 -0
- package/src/technologies/styling/daisyui.yaml +20 -0
- package/src/technologies/styling/material-ui.yaml +22 -0
- package/src/technologies/styling/shadcn-ui.yaml +20 -0
- package/src/technologies/styling/tailwindcss.yaml +20 -0
- package/tsconfig.json +11 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Learning Resources — Curated learning paths for technologies in the registry.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface LearningResource {
|
|
6
|
+
title: string;
|
|
7
|
+
url: string;
|
|
8
|
+
type: "docs" | "tutorial" | "video" | "course" | "book";
|
|
9
|
+
difficulty: "beginner" | "intermediate" | "advanced";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const LEARNING_RESOURCES: Record<string, LearningResource[]> = {
|
|
13
|
+
nextjs: [
|
|
14
|
+
{
|
|
15
|
+
title: "Official Documentation",
|
|
16
|
+
url: "https://nextjs.org/docs",
|
|
17
|
+
type: "docs",
|
|
18
|
+
difficulty: "beginner",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
title: "Learn Next.js",
|
|
22
|
+
url: "https://nextjs.org/learn",
|
|
23
|
+
type: "tutorial",
|
|
24
|
+
difficulty: "beginner",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
title: "App Router Deep Dive",
|
|
28
|
+
url: "https://nextjs.org/docs/app",
|
|
29
|
+
type: "docs",
|
|
30
|
+
difficulty: "intermediate",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
title: "Data Fetching Patterns",
|
|
34
|
+
url: "https://nextjs.org/docs/app/building-your-application/data-fetching",
|
|
35
|
+
type: "docs",
|
|
36
|
+
difficulty: "advanced",
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
|
|
40
|
+
react: [
|
|
41
|
+
{
|
|
42
|
+
title: "Official Documentation",
|
|
43
|
+
url: "https://react.dev",
|
|
44
|
+
type: "docs",
|
|
45
|
+
difficulty: "beginner",
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
title: "React Quick Start",
|
|
49
|
+
url: "https://react.dev/learn",
|
|
50
|
+
type: "tutorial",
|
|
51
|
+
difficulty: "beginner",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
title: "Thinking in React",
|
|
55
|
+
url: "https://react.dev/learn/thinking-in-react",
|
|
56
|
+
type: "tutorial",
|
|
57
|
+
difficulty: "intermediate",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
title: "React Server Components",
|
|
61
|
+
url: "https://react.dev/reference/rsc/server-components",
|
|
62
|
+
type: "docs",
|
|
63
|
+
difficulty: "advanced",
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
|
|
67
|
+
vue: [
|
|
68
|
+
{
|
|
69
|
+
title: "Official Documentation",
|
|
70
|
+
url: "https://vuejs.org/guide/introduction.html",
|
|
71
|
+
type: "docs",
|
|
72
|
+
difficulty: "beginner",
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
title: "Vue Tutorial",
|
|
76
|
+
url: "https://vuejs.org/tutorial/",
|
|
77
|
+
type: "tutorial",
|
|
78
|
+
difficulty: "beginner",
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
title: "Composition API In-Depth",
|
|
82
|
+
url: "https://vuejs.org/guide/extras/composition-api-faq.html",
|
|
83
|
+
type: "docs",
|
|
84
|
+
difficulty: "intermediate",
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
|
|
88
|
+
svelte: [
|
|
89
|
+
{
|
|
90
|
+
title: "Official Documentation",
|
|
91
|
+
url: "https://svelte.dev/docs",
|
|
92
|
+
type: "docs",
|
|
93
|
+
difficulty: "beginner",
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
title: "Svelte Interactive Tutorial",
|
|
97
|
+
url: "https://learn.svelte.dev/",
|
|
98
|
+
type: "tutorial",
|
|
99
|
+
difficulty: "beginner",
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
title: "SvelteKit Documentation",
|
|
103
|
+
url: "https://svelte.dev/docs/kit/introduction",
|
|
104
|
+
type: "docs",
|
|
105
|
+
difficulty: "intermediate",
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
|
|
109
|
+
express: [
|
|
110
|
+
{
|
|
111
|
+
title: "Official Documentation",
|
|
112
|
+
url: "https://expressjs.com/",
|
|
113
|
+
type: "docs",
|
|
114
|
+
difficulty: "beginner",
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
title: "Getting Started Guide",
|
|
118
|
+
url: "https://expressjs.com/en/starter/installing.html",
|
|
119
|
+
type: "tutorial",
|
|
120
|
+
difficulty: "beginner",
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
title: "Advanced Routing",
|
|
124
|
+
url: "https://expressjs.com/en/guide/routing.html",
|
|
125
|
+
type: "docs",
|
|
126
|
+
difficulty: "intermediate",
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
|
|
130
|
+
fastapi: [
|
|
131
|
+
{
|
|
132
|
+
title: "Official Documentation",
|
|
133
|
+
url: "https://fastapi.tiangolo.com/",
|
|
134
|
+
type: "docs",
|
|
135
|
+
difficulty: "beginner",
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
title: "FastAPI Tutorial",
|
|
139
|
+
url: "https://fastapi.tiangolo.com/tutorial/",
|
|
140
|
+
type: "tutorial",
|
|
141
|
+
difficulty: "beginner",
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
title: "Advanced User Guide",
|
|
145
|
+
url: "https://fastapi.tiangolo.com/advanced/",
|
|
146
|
+
type: "docs",
|
|
147
|
+
difficulty: "advanced",
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
|
|
151
|
+
django: [
|
|
152
|
+
{
|
|
153
|
+
title: "Official Documentation",
|
|
154
|
+
url: "https://docs.djangoproject.com/",
|
|
155
|
+
type: "docs",
|
|
156
|
+
difficulty: "beginner",
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
title: "Django Tutorial",
|
|
160
|
+
url: "https://docs.djangoproject.com/en/stable/intro/tutorial01/",
|
|
161
|
+
type: "tutorial",
|
|
162
|
+
difficulty: "beginner",
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
title: "Django REST Framework",
|
|
166
|
+
url: "https://www.django-rest-framework.org/tutorial/quickstart/",
|
|
167
|
+
type: "tutorial",
|
|
168
|
+
difficulty: "intermediate",
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
title: "Django Performance Optimization",
|
|
172
|
+
url: "https://docs.djangoproject.com/en/stable/topics/performance/",
|
|
173
|
+
type: "docs",
|
|
174
|
+
difficulty: "advanced",
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
|
|
178
|
+
nestjs: [
|
|
179
|
+
{
|
|
180
|
+
title: "Official Documentation",
|
|
181
|
+
url: "https://docs.nestjs.com/",
|
|
182
|
+
type: "docs",
|
|
183
|
+
difficulty: "beginner",
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
title: "First Steps",
|
|
187
|
+
url: "https://docs.nestjs.com/first-steps",
|
|
188
|
+
type: "tutorial",
|
|
189
|
+
difficulty: "beginner",
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
title: "Custom Decorators & Guards",
|
|
193
|
+
url: "https://docs.nestjs.com/guards",
|
|
194
|
+
type: "docs",
|
|
195
|
+
difficulty: "intermediate",
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
title: "Microservices",
|
|
199
|
+
url: "https://docs.nestjs.com/microservices/basics",
|
|
200
|
+
type: "docs",
|
|
201
|
+
difficulty: "advanced",
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
|
|
205
|
+
postgresql: [
|
|
206
|
+
{
|
|
207
|
+
title: "Official Documentation",
|
|
208
|
+
url: "https://www.postgresql.org/docs/current/",
|
|
209
|
+
type: "docs",
|
|
210
|
+
difficulty: "beginner",
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
title: "PostgreSQL Tutorial",
|
|
214
|
+
url: "https://www.postgresql.org/docs/current/tutorial.html",
|
|
215
|
+
type: "tutorial",
|
|
216
|
+
difficulty: "beginner",
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
title: "Performance Tips",
|
|
220
|
+
url: "https://www.postgresql.org/docs/current/performance-tips.html",
|
|
221
|
+
type: "docs",
|
|
222
|
+
difficulty: "intermediate",
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
title: "Indexing Best Practices",
|
|
226
|
+
url: "https://www.postgresql.org/docs/current/indexes.html",
|
|
227
|
+
type: "docs",
|
|
228
|
+
difficulty: "advanced",
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
|
|
232
|
+
mongodb: [
|
|
233
|
+
{
|
|
234
|
+
title: "Official Documentation",
|
|
235
|
+
url: "https://www.mongodb.com/docs/manual/",
|
|
236
|
+
type: "docs",
|
|
237
|
+
difficulty: "beginner",
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
title: "MongoDB University",
|
|
241
|
+
url: "https://learn.mongodb.com/",
|
|
242
|
+
type: "course",
|
|
243
|
+
difficulty: "beginner",
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
title: "Aggregation Pipeline",
|
|
247
|
+
url: "https://www.mongodb.com/docs/manual/aggregation/",
|
|
248
|
+
type: "docs",
|
|
249
|
+
difficulty: "intermediate",
|
|
250
|
+
},
|
|
251
|
+
],
|
|
252
|
+
|
|
253
|
+
redis: [
|
|
254
|
+
{
|
|
255
|
+
title: "Official Documentation",
|
|
256
|
+
url: "https://redis.io/docs/latest/",
|
|
257
|
+
type: "docs",
|
|
258
|
+
difficulty: "beginner",
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
title: "Redis University",
|
|
262
|
+
url: "https://university.redis.io/",
|
|
263
|
+
type: "course",
|
|
264
|
+
difficulty: "beginner",
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
title: "Data Structures In-Depth",
|
|
268
|
+
url: "https://redis.io/docs/latest/develop/data-types/",
|
|
269
|
+
type: "docs",
|
|
270
|
+
difficulty: "intermediate",
|
|
271
|
+
},
|
|
272
|
+
],
|
|
273
|
+
|
|
274
|
+
prisma: [
|
|
275
|
+
{
|
|
276
|
+
title: "Official Documentation",
|
|
277
|
+
url: "https://www.prisma.io/docs",
|
|
278
|
+
type: "docs",
|
|
279
|
+
difficulty: "beginner",
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
title: "Quickstart",
|
|
283
|
+
url: "https://www.prisma.io/docs/getting-started/quickstart",
|
|
284
|
+
type: "tutorial",
|
|
285
|
+
difficulty: "beginner",
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
title: "Advanced Query Patterns",
|
|
289
|
+
url: "https://www.prisma.io/docs/orm/prisma-client/queries",
|
|
290
|
+
type: "docs",
|
|
291
|
+
difficulty: "intermediate",
|
|
292
|
+
},
|
|
293
|
+
],
|
|
294
|
+
|
|
295
|
+
drizzle: [
|
|
296
|
+
{
|
|
297
|
+
title: "Official Documentation",
|
|
298
|
+
url: "https://orm.drizzle.team/docs/overview",
|
|
299
|
+
type: "docs",
|
|
300
|
+
difficulty: "beginner",
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
title: "Getting Started",
|
|
304
|
+
url: "https://orm.drizzle.team/docs/get-started",
|
|
305
|
+
type: "tutorial",
|
|
306
|
+
difficulty: "beginner",
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
title: "Joins & Relations",
|
|
310
|
+
url: "https://orm.drizzle.team/docs/joins",
|
|
311
|
+
type: "docs",
|
|
312
|
+
difficulty: "intermediate",
|
|
313
|
+
},
|
|
314
|
+
],
|
|
315
|
+
|
|
316
|
+
tailwindcss: [
|
|
317
|
+
{
|
|
318
|
+
title: "Official Documentation",
|
|
319
|
+
url: "https://tailwindcss.com/docs",
|
|
320
|
+
type: "docs",
|
|
321
|
+
difficulty: "beginner",
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
title: "Installation Guide",
|
|
325
|
+
url: "https://tailwindcss.com/docs/installation",
|
|
326
|
+
type: "tutorial",
|
|
327
|
+
difficulty: "beginner",
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
title: "Customizing Your Theme",
|
|
331
|
+
url: "https://tailwindcss.com/docs/theme",
|
|
332
|
+
type: "docs",
|
|
333
|
+
difficulty: "intermediate",
|
|
334
|
+
},
|
|
335
|
+
],
|
|
336
|
+
|
|
337
|
+
typescript: [
|
|
338
|
+
{
|
|
339
|
+
title: "Official Documentation",
|
|
340
|
+
url: "https://www.typescriptlang.org/docs/",
|
|
341
|
+
type: "docs",
|
|
342
|
+
difficulty: "beginner",
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
title: "TypeScript Handbook",
|
|
346
|
+
url: "https://www.typescriptlang.org/docs/handbook/intro.html",
|
|
347
|
+
type: "tutorial",
|
|
348
|
+
difficulty: "beginner",
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
title: "Advanced Types",
|
|
352
|
+
url: "https://www.typescriptlang.org/docs/handbook/2/types-from-types.html",
|
|
353
|
+
type: "docs",
|
|
354
|
+
difficulty: "intermediate",
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
title: "Type Challenges",
|
|
358
|
+
url: "https://github.com/type-challenges/type-challenges",
|
|
359
|
+
type: "tutorial",
|
|
360
|
+
difficulty: "advanced",
|
|
361
|
+
},
|
|
362
|
+
],
|
|
363
|
+
|
|
364
|
+
docker: [
|
|
365
|
+
{
|
|
366
|
+
title: "Official Documentation",
|
|
367
|
+
url: "https://docs.docker.com/",
|
|
368
|
+
type: "docs",
|
|
369
|
+
difficulty: "beginner",
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
title: "Getting Started",
|
|
373
|
+
url: "https://docs.docker.com/get-started/",
|
|
374
|
+
type: "tutorial",
|
|
375
|
+
difficulty: "beginner",
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
title: "Docker Compose",
|
|
379
|
+
url: "https://docs.docker.com/compose/",
|
|
380
|
+
type: "docs",
|
|
381
|
+
difficulty: "intermediate",
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
title: "Multi-Stage Builds",
|
|
385
|
+
url: "https://docs.docker.com/build/building/multi-stage/",
|
|
386
|
+
type: "docs",
|
|
387
|
+
difficulty: "advanced",
|
|
388
|
+
},
|
|
389
|
+
],
|
|
390
|
+
|
|
391
|
+
vitest: [
|
|
392
|
+
{
|
|
393
|
+
title: "Official Documentation",
|
|
394
|
+
url: "https://vitest.dev/guide/",
|
|
395
|
+
type: "docs",
|
|
396
|
+
difficulty: "beginner",
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
title: "Getting Started",
|
|
400
|
+
url: "https://vitest.dev/guide/",
|
|
401
|
+
type: "tutorial",
|
|
402
|
+
difficulty: "beginner",
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
title: "Mocking",
|
|
406
|
+
url: "https://vitest.dev/guide/mocking.html",
|
|
407
|
+
type: "docs",
|
|
408
|
+
difficulty: "intermediate",
|
|
409
|
+
},
|
|
410
|
+
],
|
|
411
|
+
|
|
412
|
+
git: [
|
|
413
|
+
{
|
|
414
|
+
title: "Official Documentation",
|
|
415
|
+
url: "https://git-scm.com/doc",
|
|
416
|
+
type: "docs",
|
|
417
|
+
difficulty: "beginner",
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
title: "Pro Git Book",
|
|
421
|
+
url: "https://git-scm.com/book/en/v2",
|
|
422
|
+
type: "book",
|
|
423
|
+
difficulty: "beginner",
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
title: "Interactive Branching Tutorial",
|
|
427
|
+
url: "https://learngitbranching.js.org/",
|
|
428
|
+
type: "tutorial",
|
|
429
|
+
difficulty: "intermediate",
|
|
430
|
+
},
|
|
431
|
+
],
|
|
432
|
+
|
|
433
|
+
nginx: [
|
|
434
|
+
{
|
|
435
|
+
title: "Official Documentation",
|
|
436
|
+
url: "https://nginx.org/en/docs/",
|
|
437
|
+
type: "docs",
|
|
438
|
+
difficulty: "beginner",
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
title: "Beginner's Guide",
|
|
442
|
+
url: "https://nginx.org/en/docs/beginners_guide.html",
|
|
443
|
+
type: "tutorial",
|
|
444
|
+
difficulty: "beginner",
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
title: "Reverse Proxy Configuration",
|
|
448
|
+
url: "https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/",
|
|
449
|
+
type: "docs",
|
|
450
|
+
difficulty: "intermediate",
|
|
451
|
+
},
|
|
452
|
+
],
|
|
453
|
+
|
|
454
|
+
python: [
|
|
455
|
+
{
|
|
456
|
+
title: "Official Documentation",
|
|
457
|
+
url: "https://docs.python.org/3/",
|
|
458
|
+
type: "docs",
|
|
459
|
+
difficulty: "beginner",
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
title: "Python Tutorial",
|
|
463
|
+
url: "https://docs.python.org/3/tutorial/",
|
|
464
|
+
type: "tutorial",
|
|
465
|
+
difficulty: "beginner",
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
title: "Real Python Tutorials",
|
|
469
|
+
url: "https://realpython.com/",
|
|
470
|
+
type: "tutorial",
|
|
471
|
+
difficulty: "intermediate",
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
title: "Python Design Patterns",
|
|
475
|
+
url: "https://python-patterns.guide/",
|
|
476
|
+
type: "docs",
|
|
477
|
+
difficulty: "advanced",
|
|
478
|
+
},
|
|
479
|
+
],
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Get learning resources for a technology by its ID.
|
|
484
|
+
* Returns undefined if no resources are available.
|
|
485
|
+
*/
|
|
486
|
+
export function getLearningResources(technologyId: string): LearningResource[] | undefined {
|
|
487
|
+
return LEARNING_RESOURCES[technologyId];
|
|
488
|
+
}
|
package/src/loader.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry Loader — Reads and validates technology YAML files.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as fs from "node:fs";
|
|
6
|
+
import * as path from "node:path";
|
|
7
|
+
import type { Technology } from "@stackweld/core";
|
|
8
|
+
import Ajv from "ajv";
|
|
9
|
+
import { parse as parseYaml } from "yaml";
|
|
10
|
+
import { technologySchema } from "./schema.js";
|
|
11
|
+
|
|
12
|
+
const ajv = new Ajv({ allErrors: true });
|
|
13
|
+
const validate = ajv.compile(technologySchema);
|
|
14
|
+
|
|
15
|
+
// Resolve technologies directory — works from both src/ (dev) and dist/ (build)
|
|
16
|
+
const thisDir = path.dirname(new URL(import.meta.url).pathname);
|
|
17
|
+
const distTechDir = path.join(thisDir, "technologies");
|
|
18
|
+
const srcTechDir = path.join(thisDir, "..", "src", "technologies");
|
|
19
|
+
const TECH_DIR = fs.existsSync(distTechDir) ? distTechDir : srcTechDir;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Load all technologies from the YAML registry.
|
|
23
|
+
* Validates each one against the JSON Schema.
|
|
24
|
+
*/
|
|
25
|
+
export function loadAllTechnologies(): Technology[] {
|
|
26
|
+
const technologies: Technology[] = [];
|
|
27
|
+
const categories = fs.readdirSync(TECH_DIR);
|
|
28
|
+
|
|
29
|
+
for (const category of categories) {
|
|
30
|
+
const categoryPath = path.join(TECH_DIR, category);
|
|
31
|
+
if (!fs.statSync(categoryPath).isDirectory()) continue;
|
|
32
|
+
|
|
33
|
+
const files = fs
|
|
34
|
+
.readdirSync(categoryPath)
|
|
35
|
+
.filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
|
|
36
|
+
|
|
37
|
+
for (const file of files) {
|
|
38
|
+
const filePath = path.join(categoryPath, file);
|
|
39
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
40
|
+
const data = parseYaml(raw);
|
|
41
|
+
|
|
42
|
+
if (!validate(data)) {
|
|
43
|
+
const errors = validate.errors?.map((e) => `${e.instancePath}: ${e.message}`).join(", ");
|
|
44
|
+
throw new Error(`Invalid technology file ${file}: ${errors}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
technologies.push(data as Technology);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return technologies;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Load a single technology by ID.
|
|
56
|
+
*/
|
|
57
|
+
export function loadTechnology(id: string): Technology | null {
|
|
58
|
+
const all = loadAllTechnologies();
|
|
59
|
+
return all.find((t) => t.id === id) ?? null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get all technology IDs.
|
|
64
|
+
*/
|
|
65
|
+
export function listTechnologyIds(): string[] {
|
|
66
|
+
return loadAllTechnologies().map((t) => t.id);
|
|
67
|
+
}
|
package/src/schema.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Schema for technology YAML files.
|
|
3
|
+
* Validated with ajv on load.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const technologySchema = {
|
|
7
|
+
type: "object",
|
|
8
|
+
required: [
|
|
9
|
+
"id",
|
|
10
|
+
"name",
|
|
11
|
+
"category",
|
|
12
|
+
"description",
|
|
13
|
+
"website",
|
|
14
|
+
"versions",
|
|
15
|
+
"defaultVersion",
|
|
16
|
+
"requires",
|
|
17
|
+
"incompatibleWith",
|
|
18
|
+
"suggestedWith",
|
|
19
|
+
"envVars",
|
|
20
|
+
"configFiles",
|
|
21
|
+
"lastVerified",
|
|
22
|
+
"tags",
|
|
23
|
+
],
|
|
24
|
+
properties: {
|
|
25
|
+
id: { type: "string", pattern: "^[a-z][a-z0-9-]*$" },
|
|
26
|
+
name: { type: "string", minLength: 1 },
|
|
27
|
+
category: {
|
|
28
|
+
type: "string",
|
|
29
|
+
enum: [
|
|
30
|
+
"runtime",
|
|
31
|
+
"frontend",
|
|
32
|
+
"backend",
|
|
33
|
+
"database",
|
|
34
|
+
"orm",
|
|
35
|
+
"auth",
|
|
36
|
+
"styling",
|
|
37
|
+
"service",
|
|
38
|
+
"devops",
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
description: { type: "string" },
|
|
42
|
+
website: { type: "string" },
|
|
43
|
+
versions: {
|
|
44
|
+
type: "array",
|
|
45
|
+
minItems: 1,
|
|
46
|
+
items: {
|
|
47
|
+
type: "object",
|
|
48
|
+
required: ["version"],
|
|
49
|
+
properties: {
|
|
50
|
+
version: { type: "string" },
|
|
51
|
+
eol: { type: "string" },
|
|
52
|
+
lts: { type: "boolean" },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
defaultVersion: { type: "string" },
|
|
57
|
+
defaultPort: { type: "integer", minimum: 1, maximum: 65535 },
|
|
58
|
+
requires: { type: "array", items: { type: "string" } },
|
|
59
|
+
incompatibleWith: { type: "array", items: { type: "string" } },
|
|
60
|
+
suggestedWith: { type: "array", items: { type: "string" } },
|
|
61
|
+
officialScaffold: { type: ["string", "null"] },
|
|
62
|
+
dockerImage: { type: ["string", "null"] },
|
|
63
|
+
healthCheck: {
|
|
64
|
+
type: "object",
|
|
65
|
+
properties: {
|
|
66
|
+
command: { type: "string" },
|
|
67
|
+
endpoint: { type: "string" },
|
|
68
|
+
interval: { type: "string" },
|
|
69
|
+
timeout: { type: "string" },
|
|
70
|
+
retries: { type: "integer" },
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
envVars: { type: "object", additionalProperties: { type: "string" } },
|
|
74
|
+
configFiles: { type: "array", items: { type: "string" } },
|
|
75
|
+
lastVerified: { type: "string" },
|
|
76
|
+
tags: { type: "array", items: { type: "string" } },
|
|
77
|
+
},
|
|
78
|
+
additionalProperties: false,
|
|
79
|
+
} as const;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
id: clerk
|
|
2
|
+
name: Clerk
|
|
3
|
+
category: auth
|
|
4
|
+
description: Drop-in authentication and user management with prebuilt UI components and multi-tenant support
|
|
5
|
+
website: https://clerk.com
|
|
6
|
+
versions:
|
|
7
|
+
- version: "6.0"
|
|
8
|
+
- version: "5.12"
|
|
9
|
+
lts: true
|
|
10
|
+
- version: "4.29"
|
|
11
|
+
eol: "2025-01-01"
|
|
12
|
+
defaultVersion: "6.0"
|
|
13
|
+
requires: [nodejs]
|
|
14
|
+
incompatibleWith: [nextauth, supabase-auth, lucia]
|
|
15
|
+
suggestedWith: [nextjs, react]
|
|
16
|
+
officialScaffold: npx create-next-app@latest --example with-clerk
|
|
17
|
+
dockerImage: null
|
|
18
|
+
healthCheck:
|
|
19
|
+
endpoint: /api/clerk/health
|
|
20
|
+
interval: "30s"
|
|
21
|
+
timeout: "5s"
|
|
22
|
+
retries: 3
|
|
23
|
+
envVars:
|
|
24
|
+
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: pk_test_your-key
|
|
25
|
+
CLERK_SECRET_KEY: sk_test_your-key
|
|
26
|
+
configFiles:
|
|
27
|
+
- middleware.ts
|
|
28
|
+
lastVerified: "2026-03-22"
|
|
29
|
+
tags: [auth, clerk, authentication, user-management, oauth, sso, multi-tenant]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
id: lucia
|
|
2
|
+
name: Lucia
|
|
3
|
+
category: auth
|
|
4
|
+
description: Simple and flexible auth library for TypeScript with session management
|
|
5
|
+
website: https://lucia-auth.com
|
|
6
|
+
versions:
|
|
7
|
+
- version: "3.2"
|
|
8
|
+
- version: "3.1"
|
|
9
|
+
defaultVersion: "3.2"
|
|
10
|
+
requires: [nodejs]
|
|
11
|
+
incompatibleWith: [nextauth, clerk, supabase-auth]
|
|
12
|
+
suggestedWith: [typescript, prisma, drizzle]
|
|
13
|
+
officialScaffold: null
|
|
14
|
+
dockerImage: null
|
|
15
|
+
envVars: {}
|
|
16
|
+
configFiles:
|
|
17
|
+
- package.json
|
|
18
|
+
lastVerified: "2026-03-22"
|
|
19
|
+
tags: [lucia, auth, session, typescript, authentication]
|