Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 176 additions & 1 deletion api/routes/_.context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,179 @@
*
* See https://counterfact.dev/docs/usage.html#working-with-state-the-codecontextcode-object-and-codecontexttscode
*/
export class Context {}

import type { Pet } from "../types/components/schemas/Pet.js";
import type { User } from "../types/components/schemas/User.js";
import type { Order } from "../types/components/schemas/Order.js";

export class Context {
pets: Pet[] = [
{
id: 1,
name: "Buddy",
category: { id: 1, name: "Dogs" },
photoUrls: ["https://example.com/buddy.jpg"],
tags: [{ id: 1, name: "friendly" }],
status: "available",
},
{
id: 2,
name: "Whiskers",
category: { id: 2, name: "Cats" },
photoUrls: ["https://example.com/whiskers.jpg"],
tags: [{ id: 2, name: "indoor" }],
status: "available",
},
{
id: 3,
name: "Goldie",
category: { id: 3, name: "Fish" },
photoUrls: ["https://example.com/goldie.jpg"],
tags: [],
status: "pending",
},
{
id: 4,
name: "Max",
category: { id: 1, name: "Dogs" },
photoUrls: ["https://example.com/max.jpg"],
tags: [{ id: 3, name: "trained" }],
status: "sold",
},
];

users: User[] = [
{
id: 1,
username: "user1",
firstName: "John",
lastName: "Doe",
email: "john@example.com",
password: "password123",
phone: "555-1234",
userStatus: 1,
},
{
id: 2,
username: "jane_smith",
firstName: "Jane",
lastName: "Smith",
email: "jane@example.com",
password: "secret456",
phone: "555-5678",
userStatus: 1,
},
];

orders: Order[] = [
{
id: 1,
petId: 1,
quantity: 1,
shipDate: "2024-01-15T10:00:00Z",
status: "placed",
complete: false,
},
{
id: 2,
petId: 4,
quantity: 1,
shipDate: "2024-01-10T08:00:00Z",
status: "delivered",
complete: true,
},
];

private nextPetId = 5;
private nextUserId = 3;
private nextOrderId = 3;

addPet(pet: Pet): Pet {
const newPet = { ...pet, id: this.nextPetId++ };
this.pets.push(newPet);
return newPet;
}

updatePet(pet: Pet): Pet | undefined {
const index = this.pets.findIndex((p) => p.id === pet.id);
if (index === -1) return undefined;
this.pets[index] = pet;
return pet;
}

getPetById(id: number): Pet | undefined {
return this.pets.find((p) => p.id === id);
}

deletePet(id: number): boolean {
const index = this.pets.findIndex((p) => p.id === id);
if (index === -1) return false;
this.pets.splice(index, 1);
return true;
}

findPetsByStatus(status: "available" | "pending" | "sold"): Pet[] {
return this.pets.filter((p) => p.status === status);
}

findPetsByTags(tags: string[]): Pet[] {
return this.pets.filter((p) =>
p.tags?.some((t) => t.name !== undefined && tags.includes(t.name)),
);
}

addUser(user: User): User {
const newUser = { ...user, id: this.nextUserId++ };
this.users.push(newUser);
return newUser;
}

getUserByUsername(username: string): User | undefined {
return this.users.find((u) => u.username === username);
}

updateUser(username: string, user: User): User | undefined {
const index = this.users.findIndex((u) => u.username === username);
if (index === -1) return undefined;
this.users[index] = { ...user, username };
return this.users[index];
}

deleteUser(username: string): boolean {
const index = this.users.findIndex((u) => u.username === username);
if (index === -1) return false;
this.users.splice(index, 1);
return true;
}

placeOrder(order: Order): Order {
const newOrder = { ...order, id: this.nextOrderId++ };
this.orders.push(newOrder);
return newOrder;
}

getOrderById(id: number): Order | undefined {
return this.orders.find((o) => o.id === id);
}

deleteOrder(id: number): boolean {
const index = this.orders.findIndex((o) => o.id === id);
if (index === -1) return false;
this.orders.splice(index, 1);
return true;
}

getInventory(): { [key: string]: number } {
const inventory: { [key: string]: number } = {
available: 0,
pending: 0,
sold: 0,
};
for (const pet of this.pets) {
if (pet.status) {
inventory[pet.status] = (inventory[pet.status] ?? 0) + 1;
}
}
return inventory;
}
}
16 changes: 12 additions & 4 deletions api/routes/pet.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import type { updatePet } from "../types/paths/pet.types.js";
import type { addPet } from "../types/paths/pet.types.js";

export const PUT: updatePet = async ($) => {
return $.response[200].random();
export const PUT: updatePet = ($) => {
if (!$.body.id) {
return $.response[400];
}
const updated = $.context.updatePet($.body);
if (!updated) {
return $.response[404];
}
return $.response[200].json(updated);
};

export const POST: addPet = async ($) => {
return $.response[200].random();
export const POST: addPet = ($) => {
const pet = $.context.addPet($.body);
return $.response[200].json(pet);
};
5 changes: 3 additions & 2 deletions api/routes/pet/findByStatus.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { findPetsByStatus } from "../../types/paths/pet/findByStatus.types.js";

export const GET: findPetsByStatus = async ($) => {
return $.response[200].random();
export const GET: findPetsByStatus = ($) => {
const pets = $.context.findPetsByStatus($.query.status);
return $.response[200].json(pets);
};
5 changes: 3 additions & 2 deletions api/routes/pet/findByTags.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { findPetsByTags } from "../../types/paths/pet/findByTags.types.js";

export const GET: findPetsByTags = async ($) => {
return $.response[200].random();
export const GET: findPetsByTags = ($) => {
const pets = $.context.findPetsByTags($.query.tags);
return $.response[200].json(pets);
};
32 changes: 27 additions & 5 deletions api/routes/pet/{petId}.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,36 @@ import type { getPetById } from "../../types/paths/pet/{petId}.types.js";
import type { updatePetWithForm } from "../../types/paths/pet/{petId}.types.js";
import type { deletePet } from "../../types/paths/pet/{petId}.types.js";

export const GET: getPetById = async ($) => {
return $.response[200].random();
export const GET: getPetById = ($) => {
const pet = $.context.getPetById($.path.petId);
if (!pet) {
return $.response[404];
}
return $.response[200].json(pet);
};

export const POST: updatePetWithForm = async ($) => {
return $.response[200].random();
export const POST: updatePetWithForm = ($) => {
const pet = $.context.getPetById($.path.petId);
if (!pet) {
return $.response[400];
}
const updated = $.context.updatePet({
...pet,
...($.query.name !== undefined ? { name: $.query.name } : {}),
...($.query.status !== undefined
? { status: $.query.status as "available" | "pending" | "sold" }
: {}),
});
if (!updated) {
return $.response[400];
}
return $.response[200].json(updated);
};

export const DELETE: deletePet = async ($) => {
export const DELETE: deletePet = ($) => {
const deleted = $.context.deletePet($.path.petId);
if (!deleted) {
return $.response[400];
}
return $.response[200];
};
12 changes: 10 additions & 2 deletions api/routes/pet/{petId}/uploadImage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import type { uploadFile } from "../../../types/paths/pet/{petId}/uploadImage.types.js";

export const POST: uploadFile = async ($) => {
return $.response[200].random();
export const POST: uploadFile = ($) => {
const pet = $.context.getPetById($.path.petId);
if (!pet) {
return $.response[404];
}
return $.response[200].json({
code: 200,
type: "unknown",
message: `File uploaded for pet ${$.path.petId}`,
});
};
5 changes: 3 additions & 2 deletions api/routes/store/inventory.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { getInventory } from "../../types/paths/store/inventory.types.js";

export const GET: getInventory = async ($) => {
return $.response[200].random();
export const GET: getInventory = ($) => {
const inventory = $.context.getInventory();
return $.response[200].json(inventory);
};
5 changes: 3 additions & 2 deletions api/routes/store/order.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { placeOrder } from "../../types/paths/store/order.types.js";

export const POST: placeOrder = async ($) => {
return $.response[200].random();
export const POST: placeOrder = ($) => {
const order = $.context.placeOrder($.body);
return $.response[200].json(order);
};
14 changes: 11 additions & 3 deletions api/routes/store/order/{orderId}.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import type { getOrderById } from "../../../types/paths/store/order/{orderId}.types.js";
import type { deleteOrder } from "../../../types/paths/store/order/{orderId}.types.js";

export const GET: getOrderById = async ($) => {
return $.response[200].random();
export const GET: getOrderById = ($) => {
const order = $.context.getOrderById($.path.orderId);
if (!order) {
return $.response[404];
}
return $.response[200].json(order);
};

export const DELETE: deleteOrder = async ($) => {
export const DELETE: deleteOrder = ($) => {
const deleted = $.context.deleteOrder($.path.orderId);
if (!deleted) {
return $.response[404];
}
return $.response[200];
};
5 changes: 3 additions & 2 deletions api/routes/user.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { createUser } from "../types/paths/user.types.js";

export const POST: createUser = async ($) => {
return $.response[200].random();
export const POST: createUser = ($) => {
const user = $.context.addUser($.body);
return $.response[200].json(user);
};
6 changes: 4 additions & 2 deletions api/routes/user/createWithList.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { createUsersWithListInput } from "../../types/paths/user/createWithList.types.js";

export const POST: createUsersWithListInput = async ($) => {
return $.response[200].random();
export const POST: createUsersWithListInput = ($) => {
const users = $.body.map((user) => $.context.addUser(user));
// The OpenAPI spec returns a single User on 200; return the first created user
return $.response[200].json(users[0]);
};
10 changes: 8 additions & 2 deletions api/routes/user/login.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type { loginUser } from "../../types/paths/user/login.types.js";

export const GET: loginUser = async ($) => {
return $.response[200].random();
export const GET: loginUser = ($) => {
const user = $.context.users.find(
(u) => u.username === $.query.username && u.password === $.query.password,
);
if (!user) {
return $.response[400];
}
return $.response[200].json(`Logged in as ${user.username}`);
};
2 changes: 1 addition & 1 deletion api/routes/user/logout.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { logoutUser } from "../../types/paths/user/logout.types.js";

export const GET: logoutUser = async ($) => {
export const GET: logoutUser = ($) => {
return $.response[200];
};
20 changes: 16 additions & 4 deletions api/routes/user/{username}.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,26 @@ import type { getUserByName } from "../../types/paths/user/{username}.types.js";
import type { updateUser } from "../../types/paths/user/{username}.types.js";
import type { deleteUser } from "../../types/paths/user/{username}.types.js";

export const GET: getUserByName = async ($) => {
return $.response[200].random();
export const GET: getUserByName = ($) => {
const user = $.context.getUserByUsername($.path.username);
if (!user) {
return $.response[404];
}
return $.response[200].json(user);
};

export const PUT: updateUser = async ($) => {
export const PUT: updateUser = ($) => {
const updated = $.context.updateUser($.path.username, $.body);
if (!updated) {
return $.response[404];
}
return $.response[200];
};

export const DELETE: deleteUser = async ($) => {
export const DELETE: deleteUser = ($) => {
const deleted = $.context.deleteUser($.path.username);
if (!deleted) {
return $.response[404];
}
return $.response[200];
};
Loading