Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update CORS #20

Merged
merged 7 commits into from
Sep 9, 2023
Merged
34 changes: 22 additions & 12 deletions examples/static-website/main.w
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,17 @@ let website = new cloud.Website(
path: "./static",
);

let api = new cloud.Api();
let api = new cloud.Api({
cors: true,
corsOptions: {
allowHeaders: ["*"],
allowMethods: [http.HttpMethod.POST],
},
});
website.addJson("config.json", { api: api.url });

let counter = new cloud.Counter() as "website-counter";

let corsHandler = inflight(req) => {
return {
headers: {
"Access-Control-Allow-Headers" => "*",
"Access-Control-Allow-Origin" => "*",
"Access-Control-Allow-Methods" => "OPTIONS,POST",
},
status: 204
};
};
api.options("/hello-static", corsHandler);
api.post("/hello-static", inflight (request) => {
return {
status: 200,
Expand All @@ -46,3 +41,18 @@ test "renders the index page" {
test "api returns the correct response" {
invokeAndAssert(http.post("${api.url}/hello-static"), "Hello 0");
}

test "api handles cors" {
let response = http.fetch("${api.url}/hello-static", {
method: http.HttpMethod.OPTIONS,
headers: {
"Origin" => "https://example.com",
"hx-target" => "hello",
},
});
assert(response.status == 204);
log("headers: ${Json.stringify(response.headers)}");
assert(response.headers.get("access-control-allow-headers") == "*");
assert(response.headers.get("access-control-allow-origin") == "*");
assert(response.headers.get("access-control-allow-methods") == "POST");
}
85 changes: 42 additions & 43 deletions examples/todo-app/main.w
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class TaskStorage impl ITaskStorage {
status: "PENDING"
};
this._add(id, taskJson);
log("adding task ${id} with data: ${taskJson}");
log("adding task ${id} with data: ${taskJson}");
return id;
}

Expand All @@ -117,8 +117,8 @@ class TaskStorage impl ITaskStorage {
}
}

inflight find(r: IRegExp): Array<Task> {
let result = MutArray<Task>[];
inflight find(r: IRegExp): Array<Task> {
let result = MutArray<Task>[];
let ids = this.db.smembers("tasks");
for id in ids {
if let taskJsonStr = this.db.get(id) {
Expand All @@ -138,46 +138,35 @@ class TaskService {

extern "./tasklist_helper.js" static inflight createRegex(s: str): IRegExp;

init() {
init(storage: ITaskStorage) {
this.api = new cloud.Api(cors: true);
this.taskStorage = new TaskStorage();

this.api.options("/tasks", inflight(req): cloud.ApiResponse => {
return {
status: 204
};
});
this.api.options("/tasks/{id}", inflight(req): cloud.ApiResponse => {
return {
status: 204
};
});

this.taskStorage = storage;

// API endpoints
this.api.post("/tasks", inflight (req): cloud.ApiResponse => {
if let body = req.body {
let var description = Json.parse(body).get("description").asStr();
// Easter Egg - if you add a task with the single word "random" as the description,
// Easter Egg - if you add a task with the single word "random" as the description,
// the system will fetch a random task from the internet
if description == "random" {
let response = http.get("https://www.boredapi.com/api/activity");
if let responseBody = response.body {
let body = Json.parse(responseBody);
description = str.fromJson(body.get("activity"));
}
}
}
let id = this.taskStorage.add(description);
return {
status:201,
return {
status:201,
body: id
};
} else {
return {
return {
status: 400,
};
}
});

this.api.put("/tasks/{id}", inflight (req): cloud.ApiResponse => {
if let body = req.body {
let id = req.vars.get("id");
Expand All @@ -188,19 +177,19 @@ class TaskService {
}
try {
if let taskJson = this.taskStorage.get(id) {
return {
status:200,
return {
status:200,
body: "${Json taskJson}"
};
}
} catch {
return {
status: 400
return {
status: 400
};
}
} else {
return {
status: 400
return {
status: 400
};
}
});
Expand All @@ -209,45 +198,55 @@ class TaskService {
let id = req.vars.get("id");
try {
if let taskJson = this.taskStorage.get(id) {
return {
status:200,
return {
status:200,
body: "${Json taskJson}"
};
}
else {
return {
status:404,
return {
status:404,
};
}
} catch {
return {
status: 400
return {
status: 400
};
}
});

this.api.delete("/tasks/{id}", inflight (req): cloud.ApiResponse => {
let id = req.vars.get("id");
try {
this.taskStorage.remove(id);
return {
return {
status: 204 };
} catch {
return {
status: 400
return {
status: 400
};
}
});

this.api.get("/tasks", inflight (req): cloud.ApiResponse => {
let search = req.query.get("search");
let results = this.taskStorage.find(TaskService.createRegex(search));
return {
status: 200,
body: "${convertTaskArrayToJson(results)}"
return {
status: 200,
body: "${convertTaskArrayToJson(results)}"
};
});
}
}

let taskService = new TaskService();
let storage = new TaskStorage();
let taskApi = new TaskService(storage);

test "list tasks" {
storage.add("task 1");
let url = taskApi.api.url;
let response = http.get("${url}/tasks");
assert(response.status == 200);
assert(response.body == Json.stringify(Json{"0":{"id":"0","description":"task 1","status":"PENDING"}}));
assert(response.headers.get("access-control-allow-origin") == "*");
}
Loading