Skip to content

Commit 8f9c16b

Browse files
committed
add kellie ��‍♂️
1 parent 08165a5 commit 8f9c16b

File tree

14 files changed

+142
-100
lines changed

14 files changed

+142
-100
lines changed

exercises/02.tools/02.solution.args/README.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,8 @@ Key learnings from this step:
2424
- How to return dynamic results based on user input
2525

2626
You're now ready to build all sorts of powerful, parameterized tools!
27+
28+
🧝‍♀️ In the next exercise, we're going to be working with a more real-world
29+
application, so I'm going to be adding a database and things. You'll have to
30+
integrate that, but if you've got a minute, you
31+
can <NextDiffLink>check out my changes</NextDiffLink> if you're curious.

exercises/03.advanced-tools/02.problem.organization/src/index.test.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,18 @@ test('Tool Definition', async () => {
2828

2929
expect(firstTool).toEqual(
3030
expect.objectContaining({
31-
name: expect.stringMatching(/^add$/i),
32-
description: expect.stringMatching(/^add two numbers$/i),
31+
name: expect.stringMatching(/^create_entry$/i),
32+
description: expect.stringMatching(/^create a new journal entry$/i),
3333
inputSchema: expect.objectContaining({
3434
type: 'object',
3535
properties: expect.objectContaining({
36-
firstNumber: expect.objectContaining({
37-
type: 'number',
38-
description: expect.stringMatching(/first/i),
36+
title: expect.objectContaining({
37+
type: 'string',
38+
description: expect.stringMatching(/title/i),
39+
}),
40+
content: expect.objectContaining({
41+
type: 'string',
42+
description: expect.stringMatching(/content/i),
3943
}),
4044
}),
4145
}),
@@ -45,10 +49,10 @@ test('Tool Definition', async () => {
4549

4650
test('Tool Call', async () => {
4751
const result = await client.callTool({
48-
name: 'add',
52+
name: 'create_entry',
4953
arguments: {
50-
firstNumber: 1,
51-
secondNumber: 2,
54+
title: 'Test Entry',
55+
content: 'This is a test entry',
5256
},
5357
})
5458

@@ -57,7 +61,9 @@ test('Tool Call', async () => {
5761
content: expect.arrayContaining([
5862
expect.objectContaining({
5963
type: 'text',
60-
text: expect.stringMatching(/3/),
64+
text: expect.stringMatching(
65+
/Entry "Test Entry" created successfully/,
66+
),
6167
}),
6268
]),
6369
}),

exercises/03.advanced-tools/02.solution.organization/src/index.test.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,18 @@ test('Tool Definition', async () => {
2828

2929
expect(firstTool).toEqual(
3030
expect.objectContaining({
31-
name: expect.stringMatching(/^add$/i),
32-
description: expect.stringMatching(/^add two numbers$/i),
31+
name: expect.stringMatching(/^create_entry$/i),
32+
description: expect.stringMatching(/^create a new journal entry$/i),
3333
inputSchema: expect.objectContaining({
3434
type: 'object',
3535
properties: expect.objectContaining({
36-
firstNumber: expect.objectContaining({
37-
type: 'number',
38-
description: expect.stringMatching(/first/i),
36+
title: expect.objectContaining({
37+
type: 'string',
38+
description: expect.stringMatching(/title/i),
39+
}),
40+
content: expect.objectContaining({
41+
type: 'string',
42+
description: expect.stringMatching(/content/i),
3943
}),
4044
}),
4145
}),
@@ -45,10 +49,10 @@ test('Tool Definition', async () => {
4549

4650
test('Tool Call', async () => {
4751
const result = await client.callTool({
48-
name: 'add',
52+
name: 'create_entry',
4953
arguments: {
50-
firstNumber: 1,
51-
secondNumber: 2,
54+
title: 'Test Entry',
55+
content: 'This is a test entry',
5256
},
5357
})
5458

@@ -57,7 +61,9 @@ test('Tool Call', async () => {
5761
content: expect.arrayContaining([
5862
expect.objectContaining({
5963
type: 'text',
60-
text: expect.stringMatching(/3/),
64+
text: expect.stringMatching(
65+
/Entry "Test Entry" created successfully/,
66+
),
6167
}),
6268
]),
6369
}),

exercises/03.advanced-tools/03.problem.class/src/index.test.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,18 @@ test('Tool Definition', async () => {
2828

2929
expect(firstTool).toEqual(
3030
expect.objectContaining({
31-
name: expect.stringMatching(/^add$/i),
32-
description: expect.stringMatching(/^add two numbers$/i),
31+
name: expect.stringMatching(/^create_entry$/i),
32+
description: expect.stringMatching(/^create a new journal entry$/i),
3333
inputSchema: expect.objectContaining({
3434
type: 'object',
3535
properties: expect.objectContaining({
36-
firstNumber: expect.objectContaining({
37-
type: 'number',
38-
description: expect.stringMatching(/first/i),
36+
title: expect.objectContaining({
37+
type: 'string',
38+
description: expect.stringMatching(/title/i),
39+
}),
40+
content: expect.objectContaining({
41+
type: 'string',
42+
description: expect.stringMatching(/content/i),
3943
}),
4044
}),
4145
}),
@@ -45,10 +49,10 @@ test('Tool Definition', async () => {
4549

4650
test('Tool Call', async () => {
4751
const result = await client.callTool({
48-
name: 'add',
52+
name: 'create_entry',
4953
arguments: {
50-
firstNumber: 1,
51-
secondNumber: 2,
54+
title: 'Test Entry',
55+
content: 'This is a test entry',
5256
},
5357
})
5458

@@ -57,7 +61,9 @@ test('Tool Call', async () => {
5761
content: expect.arrayContaining([
5862
expect.objectContaining({
5963
type: 'text',
60-
text: expect.stringMatching(/3/),
64+
text: expect.stringMatching(
65+
/Entry "Test Entry" created successfully/,
66+
),
6167
}),
6268
]),
6369
}),

exercises/03.advanced-tools/03.solution.class/README.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,7 @@ a clean, maintainable codebase.
88
👨‍💼 Thanks Olivia! Great job. With this refactor, the journaling app is now
99
easier to extend, test, and deploy in real-world scenarios. You're set up for
1010
success as your project grows!
11+
12+
🧝‍♂️ I'm going to make a little utility to get an error message from an error
13+
object. It's not complicated, but if you've got a second, you
14+
can <NextDiffLink>check out my changes</NextDiffLink>.

exercises/03.advanced-tools/03.solution.class/src/index.test.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,18 @@ test('Tool Definition', async () => {
2828

2929
expect(firstTool).toEqual(
3030
expect.objectContaining({
31-
name: expect.stringMatching(/^add$/i),
32-
description: expect.stringMatching(/^add two numbers$/i),
31+
name: expect.stringMatching(/^create_entry$/i),
32+
description: expect.stringMatching(/^create a new journal entry$/i),
3333
inputSchema: expect.objectContaining({
3434
type: 'object',
3535
properties: expect.objectContaining({
36-
firstNumber: expect.objectContaining({
37-
type: 'number',
38-
description: expect.stringMatching(/first/i),
36+
title: expect.objectContaining({
37+
type: 'string',
38+
description: expect.stringMatching(/title/i),
39+
}),
40+
content: expect.objectContaining({
41+
type: 'string',
42+
description: expect.stringMatching(/content/i),
3943
}),
4044
}),
4145
}),
@@ -45,10 +49,10 @@ test('Tool Definition', async () => {
4549

4650
test('Tool Call', async () => {
4751
const result = await client.callTool({
48-
name: 'add',
52+
name: 'create_entry',
4953
arguments: {
50-
firstNumber: 1,
51-
secondNumber: 2,
54+
title: 'Test Entry',
55+
content: 'This is a test entry',
5256
},
5357
})
5458

@@ -57,7 +61,9 @@ test('Tool Call', async () => {
5761
content: expect.arrayContaining([
5862
expect.objectContaining({
5963
type: 'text',
60-
text: expect.stringMatching(/3/),
64+
text: expect.stringMatching(
65+
/Entry "Test Entry" created successfully/,
66+
),
6167
}),
6268
]),
6369
}),

exercises/03.advanced-tools/04.problem.errors/src/db/index.ts

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,8 @@ export class DB {
6767
const stmt = this.#db.prepare(
6868
sql`SELECT * FROM entries ORDER BY created_at DESC`,
6969
)
70-
const entries = stmt.all()
71-
return z
72-
.array(entrySchema)
73-
.parse(entries.map((entry) => snakeToCamel(entry)))
70+
const entries = stmt.all().map((entry) => snakeToCamel(entry))
71+
return z.array(entrySchema).parse(entries)
7472
}
7573

7674
async getEntry(id: number) {
@@ -85,10 +83,10 @@ export class DB {
8583
WHERE et.entry_id = ?
8684
ORDER BY t.name
8785
`)
88-
const tagsResult = tagsStmt.all(id)
86+
const tagsResult = tagsStmt.all(id).map((tag) => snakeToCamel(tag))
8987
const tags = z
9088
.array(z.object({ id: z.number(), name: z.string() }))
91-
.parse(tagsResult.map((result: any) => snakeToCamel(result)))
89+
.parse(tagsResult)
9290
return { ...entry, tags }
9391
}
9492

@@ -97,10 +95,8 @@ export class DB {
9795
const stmt = this.#db.prepare(
9896
sql`SELECT * FROM entries ORDER BY created_at DESC`,
9997
)
100-
const results = stmt.all()
101-
return z
102-
.array(entrySchema)
103-
.parse(results.map((result: any) => snakeToCamel(result)))
98+
const results = stmt.all().map((result) => snakeToCamel(result))
99+
return z.array(entrySchema).parse(results)
104100
}
105101

106102
async updateEntry(
@@ -159,9 +155,6 @@ export class DB {
159155
// Tag Methods
160156
async createTag(tag: NewTag) {
161157
const validatedTag = newTagSchema.parse(tag)
162-
if (validatedTag.name.toLowerCase().includes('error')) {
163-
throw new Error('Invalid tag name. Cannot contain the word "error"')
164-
}
165158
const stmt = this.#db.prepare(sql`
166159
INSERT INTO tags (name, description)
167160
VALUES (?, ?)
@@ -183,10 +176,8 @@ export class DB {
183176

184177
async getTags() {
185178
const stmt = this.#db.prepare(sql`SELECT * FROM tags ORDER BY name`)
186-
const results = stmt.all()
187-
return z
188-
.array(tagSchema)
189-
.parse(results.map((result: any) => snakeToCamel(result)))
179+
const results = stmt.all().map((result) => snakeToCamel(result))
180+
return z.array(tagSchema).parse(results)
190181
}
191182

192183
async getTag(id: number) {
@@ -198,10 +189,10 @@ export class DB {
198189

199190
async listTags() {
200191
const stmt = this.#db.prepare(sql`SELECT id, name FROM tags ORDER BY name`)
201-
const results = stmt.all()
192+
const results = stmt.all().map((result) => snakeToCamel(result))
202193
return z
203194
.array(z.object({ id: z.number(), name: z.string() }))
204-
.parse(results.map((result: any) => snakeToCamel(result)))
195+
.parse(results)
205196
}
206197

207198
async updateTag(id: number, tag: Partial<z.input<typeof newTagSchema>>) {
@@ -302,9 +293,7 @@ export class DB {
302293
WHERE et.entry_id = ?
303294
ORDER BY t.name
304295
`)
305-
const results = stmt.all(entryId)
306-
return z
307-
.array(tagSchema)
308-
.parse(results.map((result: any) => snakeToCamel(result)))
296+
const results = stmt.all(entryId).map((result) => snakeToCamel(result))
297+
return z.array(tagSchema).parse(results)
309298
}
310299
}

exercises/03.advanced-tools/04.problem.errors/src/index.test.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,18 @@ test('Tool Definition', async () => {
2828

2929
expect(firstTool).toEqual(
3030
expect.objectContaining({
31-
name: expect.stringMatching(/^add$/i),
32-
description: expect.stringMatching(/^add two numbers$/i),
31+
name: expect.stringMatching(/^create_entry$/i),
32+
description: expect.stringMatching(/^create a new journal entry$/i),
3333
inputSchema: expect.objectContaining({
3434
type: 'object',
3535
properties: expect.objectContaining({
36-
firstNumber: expect.objectContaining({
37-
type: 'number',
38-
description: expect.stringMatching(/first/i),
36+
title: expect.objectContaining({
37+
type: 'string',
38+
description: expect.stringMatching(/title/i),
39+
}),
40+
content: expect.objectContaining({
41+
type: 'string',
42+
description: expect.stringMatching(/content/i),
3943
}),
4044
}),
4145
}),
@@ -45,10 +49,10 @@ test('Tool Definition', async () => {
4549

4650
test('Tool Call', async () => {
4751
const result = await client.callTool({
48-
name: 'add',
52+
name: 'create_entry',
4953
arguments: {
50-
firstNumber: 1,
51-
secondNumber: 2,
54+
title: 'Test Entry',
55+
content: 'This is a test entry',
5256
},
5357
})
5458

@@ -57,7 +61,9 @@ test('Tool Call', async () => {
5761
content: expect.arrayContaining([
5862
expect.objectContaining({
5963
type: 'text',
60-
text: expect.stringMatching(/3/),
64+
text: expect.stringMatching(
65+
/Entry "Test Entry" created successfully/,
66+
),
6167
}),
6268
]),
6369
}),

exercises/03.advanced-tools/04.solution.errors/README.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,8 @@ exactly what went wrong and why.
77

88
With proper error handling in place, your tools are ready for real-world use—no
99
more silent failures or confusing responses!
10+
11+
🧝‍♂️ From here we need a bunch more tools to have a full app experience. So I'm
12+
going to add all those. It's pretty much doing what you just learned over and
13+
over again, but if you'd like to try it yourself, go for it and you can compare
14+
your solution <NextDiffLink>to mine</NextDiffLink>.

0 commit comments

Comments
 (0)