create-cloudflare 2.21.9 → 2.22.1
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/dist/cli.js +8 -7
- package/package.json +9 -9
- package/templates/angular/c3.ts +1 -0
- package/templates/common/ts/package.json +1 -1
- package/templates/hello-world/ts/package.json +1 -1
- package/templates/hello-world-durable-object/ts/package.json +1 -1
- package/templates/next/README.md +1 -1
- package/templates/next/c3.ts +1 -1
- package/templates/openapi/ts/README.md +3 -3
- package/templates/openapi/ts/package.json +3 -1
- package/templates/openapi/ts/src/endpoints/taskCreate.ts +26 -16
- package/templates/openapi/ts/src/endpoints/taskDelete.ts +20 -19
- package/templates/openapi/ts/src/endpoints/taskFetch.ts +30 -23
- package/templates/openapi/ts/src/endpoints/taskList.ts +27 -24
- package/templates/openapi/ts/src/index.ts +14 -20
- package/templates/openapi/ts/src/types.ts +9 -8
- package/templates/queues/ts/package.json +1 -1
- package/templates/scheduled/ts/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2870,7 +2870,7 @@ var init_args = __esm({
|
|
|
2870
2870
|
var version;
|
|
2871
2871
|
var init_package = __esm({
|
|
2872
2872
|
"package.json"() {
|
|
2873
|
-
version = "2.
|
|
2873
|
+
version = "2.22.1";
|
|
2874
2874
|
}
|
|
2875
2875
|
});
|
|
2876
2876
|
|
|
@@ -23684,15 +23684,15 @@ var init_package2 = __esm({
|
|
|
23684
23684
|
dependencies: {
|
|
23685
23685
|
"create-astro": "4.8.0",
|
|
23686
23686
|
"create-analog": "1.3.1",
|
|
23687
|
-
"@angular/create": "18.
|
|
23687
|
+
"@angular/create": "18.1.1",
|
|
23688
23688
|
"create-docusaurus": "3.4.0",
|
|
23689
|
-
"create-hono": "0.
|
|
23689
|
+
"create-hono": "0.10.0",
|
|
23690
23690
|
"create-next-app": "14.1.0",
|
|
23691
23691
|
"create-qwik": "1.5.7",
|
|
23692
23692
|
"create-react-app": "5.0.1",
|
|
23693
|
-
"create-remix": "2.
|
|
23693
|
+
"create-remix": "2.10.3",
|
|
23694
23694
|
"create-solid": "0.5.11",
|
|
23695
|
-
"create-svelte": "6.3.
|
|
23695
|
+
"create-svelte": "6.3.3",
|
|
23696
23696
|
"create-vue": "3.10.4",
|
|
23697
23697
|
gatsby: "5.13.6",
|
|
23698
23698
|
nuxi: "3.12.0"
|
|
@@ -23771,7 +23771,7 @@ var init_frameworks = __esm({
|
|
|
23771
23771
|
var version2;
|
|
23772
23772
|
var init_package3 = __esm({
|
|
23773
23773
|
"../wrangler/package.json"() {
|
|
23774
|
-
version2 = "3.
|
|
23774
|
+
version2 = "3.65.1";
|
|
23775
23775
|
}
|
|
23776
23776
|
});
|
|
23777
23777
|
|
|
@@ -70009,6 +70009,7 @@ async function updateAppCode() {
|
|
|
70009
70009
|
const packageManifest = readJSON(packageJsonPath);
|
|
70010
70010
|
delete packageManifest["dependencies"]["@angular/ssr"];
|
|
70011
70011
|
delete packageManifest["dependencies"]["express"];
|
|
70012
|
+
delete packageManifest["devDependencies"]["@types/express"];
|
|
70012
70013
|
writeFile2(packageJsonPath, JSON.stringify(packageManifest, null, 2));
|
|
70013
70014
|
s.stop(`${brandColor(`updated`)} ${dim(`\`package.json\``)}`);
|
|
70014
70015
|
}
|
|
@@ -70372,7 +70373,7 @@ ${$1}`
|
|
|
70372
70373
|
|
|
70373
70374
|
// Here we use the @cloudflare/next-on-pages next-dev module to allow us to use bindings during local development
|
|
70374
70375
|
// (when running the application with \`next dev\`), for more information see:
|
|
70375
|
-
// https://github.com/cloudflare/next-on-pages/blob/
|
|
70376
|
+
// https://github.com/cloudflare/next-on-pages/blob/main/internal-packages/next-dev/README.md
|
|
70376
70377
|
if (process.env.NODE_ENV === 'development') {
|
|
70377
70378
|
await setupDevPlatform();
|
|
70378
70379
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-cloudflare",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.22.1",
|
|
4
4
|
"description": "A CLI for creating and deploying new applications to Cloudflare.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@babel/parser": "^7.21.3",
|
|
30
30
|
"@babel/types": "^7.21.4",
|
|
31
31
|
"@clack/prompts": "^0.6.3",
|
|
32
|
-
"@cloudflare/workers-types": "^4.
|
|
32
|
+
"@cloudflare/workers-types": "^4.20240718.0",
|
|
33
33
|
"@iarna/toml": "^3.0.0",
|
|
34
34
|
"@types/command-exists": "^1.2.0",
|
|
35
35
|
"@types/cross-spawn": "^6.0.2",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"@cloudflare/cli": "1.1.1",
|
|
68
68
|
"@cloudflare/eslint-config-worker": "1.1.0",
|
|
69
69
|
"@cloudflare/workers-tsconfig": "0.0.0",
|
|
70
|
-
"wrangler": "3.
|
|
70
|
+
"wrangler": "3.65.1"
|
|
71
71
|
},
|
|
72
72
|
"engines": {
|
|
73
73
|
"node": ">=18.14.1"
|
|
@@ -81,13 +81,13 @@
|
|
|
81
81
|
"scripts": {
|
|
82
82
|
"build": "node -r esbuild-register scripts/build.ts",
|
|
83
83
|
"dev:codemod": "node -r esbuild-register scripts/codemodDev.ts",
|
|
84
|
-
"check:lint": "eslint .",
|
|
84
|
+
"check:lint": "eslint . --max-warnings=0",
|
|
85
85
|
"check:type": "tsc",
|
|
86
|
-
"test:e2e": "vitest run --config ./vitest-e2e.config.
|
|
87
|
-
"test:e2e:npm": "pnpm run build && cross-env TEST_PM=npm vitest run --config ./vitest-e2e.config.
|
|
88
|
-
"test:e2e:pnpm": "pnpm run build && cross-env TEST_PM=pnpm vitest run --config ./vitest-e2e.config.
|
|
89
|
-
"test:e2e:bun": "pnpm run build && cross-env TEST_PM=bun vitest run --config ./vitest-e2e.config.
|
|
90
|
-
"test:e2e:yarn": "pnpm run build && cross-env TEST_PM=yarn vitest run --config ./vitest-e2e.config.
|
|
86
|
+
"test:e2e": "vitest run --config ./vitest-e2e.config.mts",
|
|
87
|
+
"test:e2e:npm": "pnpm run build && cross-env TEST_PM=npm vitest run --config ./vitest-e2e.config.mts",
|
|
88
|
+
"test:e2e:pnpm": "pnpm run build && cross-env TEST_PM=pnpm vitest run --config ./vitest-e2e.config.mts",
|
|
89
|
+
"test:e2e:bun": "pnpm run build && cross-env TEST_PM=bun vitest run --config ./vitest-e2e.config.mts",
|
|
90
|
+
"test:e2e:yarn": "pnpm run build && cross-env TEST_PM=yarn vitest run --config ./vitest-e2e.config.mts",
|
|
91
91
|
"test:unit": "vitest run --config ./vitest.config.mts",
|
|
92
92
|
"test:unit:watch": "vitest --config ./vitest.config.mts",
|
|
93
93
|
"watch": "node -r esbuild-register scripts/build.ts --watch",
|
package/templates/angular/c3.ts
CHANGED
|
@@ -57,6 +57,7 @@ async function updateAppCode() {
|
|
|
57
57
|
|
|
58
58
|
delete packageManifest["dependencies"]["@angular/ssr"];
|
|
59
59
|
delete packageManifest["dependencies"]["express"];
|
|
60
|
+
delete packageManifest["devDependencies"]["@types/express"];
|
|
60
61
|
|
|
61
62
|
writeFile(packageJsonPath, JSON.stringify(packageManifest, null, 2));
|
|
62
63
|
s.stop(`${brandColor(`updated`)} ${dim(`\`package.json\``)}`);
|
package/templates/next/README.md
CHANGED
|
@@ -23,7 +23,7 @@ Besides the `dev` script mentioned above `c3` has added a few extra scripts that
|
|
|
23
23
|
- `preview` to locally preview your Pages application using the [Wrangler](https://developers.cloudflare.com/workers/wrangler/) CLI
|
|
24
24
|
- `deploy` to deploy your Pages application using the [Wrangler](https://developers.cloudflare.com/workers/wrangler/) CLI
|
|
25
25
|
|
|
26
|
-
> __Note:__ while the `dev` script is optimal for local development you should preview your Pages application as well (periodically or before deployments) in order to make sure that it can properly work in the Pages environment (for more details see the [`@cloudflare/next-on-pages` recommended workflow](https://github.com/cloudflare/next-on-pages/blob/
|
|
26
|
+
> __Note:__ while the `dev` script is optimal for local development you should preview your Pages application as well (periodically or before deployments) in order to make sure that it can properly work in the Pages environment (for more details see the [`@cloudflare/next-on-pages` recommended workflow](https://github.com/cloudflare/next-on-pages/blob/main/internal-packages/next-dev/README.md#recommended-development-workflow))
|
|
27
27
|
|
|
28
28
|
### Bindings
|
|
29
29
|
|
package/templates/next/c3.ts
CHANGED
|
@@ -63,7 +63,7 @@ const updateNextConfig = () => {
|
|
|
63
63
|
|
|
64
64
|
// Here we use the @cloudflare/next-on-pages next-dev module to allow us to use bindings during local development
|
|
65
65
|
// (when running the application with \`next dev\`), for more information see:
|
|
66
|
-
// https://github.com/cloudflare/next-on-pages/blob/
|
|
66
|
+
// https://github.com/cloudflare/next-on-pages/blob/main/internal-packages/next-dev/README.md
|
|
67
67
|
if (process.env.NODE_ENV === 'development') {
|
|
68
68
|
await setupDevPlatform();
|
|
69
69
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Cloudflare Workers OpenAPI 3.1
|
|
2
2
|
|
|
3
|
-
This is a Cloudflare Worker with OpenAPI 3.1 using [
|
|
3
|
+
This is a Cloudflare Worker with OpenAPI 3.1 using [chanfana](https://github.com/cloudflare/chanfana) and [Hono](https://github.com/honojs/hono).
|
|
4
4
|
|
|
5
5
|
This is an example project made to be used as a quick start into building OpenAPI compliant Workers that generates the
|
|
6
6
|
`openapi.json` schema automatically from code and validates the incoming request to the defined parameters or request body.
|
|
@@ -16,10 +16,10 @@ This is an example project made to be used as a quick start into building OpenAP
|
|
|
16
16
|
|
|
17
17
|
1. Your main router is defined in `src/index.ts`.
|
|
18
18
|
2. Each endpoint has its own file in `src/endpoints/`.
|
|
19
|
-
3. For more information read the [
|
|
19
|
+
3. For more information read the [chanfana documentation](https://chanfana.pages.dev/) and [Hono documentation](https://hono.dev/docs).
|
|
20
20
|
|
|
21
21
|
## Development
|
|
22
22
|
|
|
23
23
|
1. Run `wrangler dev` to start a local instance of the API.
|
|
24
|
-
2. Open `http://localhost:
|
|
24
|
+
2. Open `http://localhost:8787/` in your browser to see the Swagger interface where you can try the endpoints.
|
|
25
25
|
3. Changes made in the `src/` folder will automatically trigger the server to reload, you only need to refresh the Swagger interface.
|
|
@@ -1,33 +1,43 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
OpenAPIRouteSchema,
|
|
4
|
-
} from "@cloudflare/itty-router-openapi";
|
|
1
|
+
import { Bool, OpenAPIRoute } from "chanfana";
|
|
2
|
+
import { z } from "zod";
|
|
5
3
|
import { Task } from "../types";
|
|
6
4
|
|
|
7
5
|
export class TaskCreate extends OpenAPIRoute {
|
|
8
|
-
|
|
6
|
+
schema = {
|
|
9
7
|
tags: ["Tasks"],
|
|
10
8
|
summary: "Create a new Task",
|
|
11
|
-
|
|
9
|
+
request: {
|
|
10
|
+
body: {
|
|
11
|
+
content: {
|
|
12
|
+
"application/json": {
|
|
13
|
+
schema: Task,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
12
18
|
responses: {
|
|
13
19
|
"200": {
|
|
14
20
|
description: "Returns the created task",
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
content: {
|
|
22
|
+
"application/json": {
|
|
23
|
+
schema: z.object({
|
|
24
|
+
series: z.object({
|
|
25
|
+
success: Bool(),
|
|
26
|
+
result: z.object({
|
|
27
|
+
task: Task,
|
|
28
|
+
}),
|
|
29
|
+
}),
|
|
30
|
+
}),
|
|
19
31
|
},
|
|
20
32
|
},
|
|
21
33
|
},
|
|
22
34
|
},
|
|
23
35
|
};
|
|
24
36
|
|
|
25
|
-
async handle(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
data: Record<string, any>
|
|
30
|
-
) {
|
|
37
|
+
async handle(c) {
|
|
38
|
+
// Get validated data
|
|
39
|
+
const data = await this.getValidatedData<typeof this.schema>();
|
|
40
|
+
|
|
31
41
|
// Retrieve the validated request body
|
|
32
42
|
const taskToCreate = data.body;
|
|
33
43
|
|
|
@@ -1,38 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
OpenAPIRouteSchema,
|
|
4
|
-
Path,
|
|
5
|
-
} from "@cloudflare/itty-router-openapi";
|
|
1
|
+
import { Bool, OpenAPIRoute, Str } from "chanfana";
|
|
2
|
+
import { z } from "zod";
|
|
6
3
|
import { Task } from "../types";
|
|
7
4
|
|
|
8
5
|
export class TaskDelete extends OpenAPIRoute {
|
|
9
|
-
|
|
6
|
+
schema = {
|
|
10
7
|
tags: ["Tasks"],
|
|
11
8
|
summary: "Delete a Task",
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
description: "Task slug",
|
|
9
|
+
request: {
|
|
10
|
+
params: z.object({
|
|
11
|
+
taskSlug: Str({ description: "Task slug" }),
|
|
15
12
|
}),
|
|
16
13
|
},
|
|
17
14
|
responses: {
|
|
18
15
|
"200": {
|
|
19
16
|
description: "Returns if the task was deleted successfully",
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
content: {
|
|
18
|
+
"application/json": {
|
|
19
|
+
schema: z.object({
|
|
20
|
+
series: z.object({
|
|
21
|
+
success: Bool(),
|
|
22
|
+
result: z.object({
|
|
23
|
+
task: Task,
|
|
24
|
+
}),
|
|
25
|
+
}),
|
|
26
|
+
}),
|
|
24
27
|
},
|
|
25
28
|
},
|
|
26
29
|
},
|
|
27
30
|
},
|
|
28
31
|
};
|
|
29
32
|
|
|
30
|
-
async handle(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
data: Record<string, any>
|
|
35
|
-
) {
|
|
33
|
+
async handle(c) {
|
|
34
|
+
// Get validated data
|
|
35
|
+
const data = await this.getValidatedData<typeof this.schema>();
|
|
36
|
+
|
|
36
37
|
// Retrieve the validated slug
|
|
37
38
|
const { taskSlug } = data.params;
|
|
38
39
|
|
|
@@ -1,45 +1,52 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
OpenAPIRouteSchema,
|
|
4
|
-
Path,
|
|
5
|
-
} from "@cloudflare/itty-router-openapi";
|
|
1
|
+
import { Bool, OpenAPIRoute, Str } from "chanfana";
|
|
2
|
+
import { z } from "zod";
|
|
6
3
|
import { Task } from "../types";
|
|
7
4
|
|
|
8
5
|
export class TaskFetch extends OpenAPIRoute {
|
|
9
|
-
|
|
6
|
+
schema = {
|
|
10
7
|
tags: ["Tasks"],
|
|
11
8
|
summary: "Get a single Task by slug",
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
description: "Task slug",
|
|
9
|
+
request: {
|
|
10
|
+
params: z.object({
|
|
11
|
+
taskSlug: Str({ description: "Task slug" }),
|
|
15
12
|
}),
|
|
16
13
|
},
|
|
17
14
|
responses: {
|
|
18
15
|
"200": {
|
|
19
16
|
description: "Returns a single task if found",
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
content: {
|
|
18
|
+
"application/json": {
|
|
19
|
+
schema: z.object({
|
|
20
|
+
series: z.object({
|
|
21
|
+
success: Bool(),
|
|
22
|
+
result: z.object({
|
|
23
|
+
task: Task,
|
|
24
|
+
}),
|
|
25
|
+
}),
|
|
26
|
+
}),
|
|
24
27
|
},
|
|
25
28
|
},
|
|
26
29
|
},
|
|
27
30
|
"404": {
|
|
28
31
|
description: "Task not found",
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
content: {
|
|
33
|
+
"application/json": {
|
|
34
|
+
schema: z.object({
|
|
35
|
+
series: z.object({
|
|
36
|
+
success: Bool(),
|
|
37
|
+
error: Str(),
|
|
38
|
+
}),
|
|
39
|
+
}),
|
|
40
|
+
},
|
|
32
41
|
},
|
|
33
42
|
},
|
|
34
43
|
},
|
|
35
44
|
};
|
|
36
45
|
|
|
37
|
-
async handle(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
data: Record<string, any>
|
|
42
|
-
) {
|
|
46
|
+
async handle(c) {
|
|
47
|
+
// Get validated data
|
|
48
|
+
const data = await this.getValidatedData<typeof this.schema>();
|
|
49
|
+
|
|
43
50
|
// Retrieve the validated slug
|
|
44
51
|
const { taskSlug } = data.params;
|
|
45
52
|
|
|
@@ -56,7 +63,7 @@ export class TaskFetch extends OpenAPIRoute {
|
|
|
56
63
|
},
|
|
57
64
|
{
|
|
58
65
|
status: 404,
|
|
59
|
-
}
|
|
66
|
+
},
|
|
60
67
|
);
|
|
61
68
|
}
|
|
62
69
|
|
|
@@ -1,43 +1,46 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
OpenAPIRouteSchema,
|
|
4
|
-
Query,
|
|
5
|
-
} from "@cloudflare/itty-router-openapi";
|
|
1
|
+
import { Bool, Num, OpenAPIRoute } from "chanfana";
|
|
2
|
+
import { z } from "zod";
|
|
6
3
|
import { Task } from "../types";
|
|
7
4
|
|
|
8
5
|
export class TaskList extends OpenAPIRoute {
|
|
9
|
-
|
|
6
|
+
schema = {
|
|
10
7
|
tags: ["Tasks"],
|
|
11
8
|
summary: "List Tasks",
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
request: {
|
|
10
|
+
query: z.object({
|
|
11
|
+
page: Num({
|
|
12
|
+
description: "Page number",
|
|
13
|
+
default: 0,
|
|
14
|
+
}),
|
|
15
|
+
isCompleted: Bool({
|
|
16
|
+
description: "Filter by completed flag",
|
|
17
|
+
required: false,
|
|
18
|
+
}),
|
|
20
19
|
}),
|
|
21
20
|
},
|
|
22
21
|
responses: {
|
|
23
22
|
"200": {
|
|
24
23
|
description: "Returns a list of tasks",
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
content: {
|
|
25
|
+
"application/json": {
|
|
26
|
+
schema: z.object({
|
|
27
|
+
series: z.object({
|
|
28
|
+
success: Bool(),
|
|
29
|
+
result: z.object({
|
|
30
|
+
tasks: Task.array(),
|
|
31
|
+
}),
|
|
32
|
+
}),
|
|
33
|
+
}),
|
|
29
34
|
},
|
|
30
35
|
},
|
|
31
36
|
},
|
|
32
37
|
},
|
|
33
38
|
};
|
|
34
39
|
|
|
35
|
-
async handle(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
data: Record<string, any>
|
|
40
|
-
) {
|
|
40
|
+
async handle(c) {
|
|
41
|
+
// Get validated data
|
|
42
|
+
const data = await this.getValidatedData<typeof this.schema>();
|
|
43
|
+
|
|
41
44
|
// Retrieve the validated parameters
|
|
42
45
|
const { page, isCompleted } = data.query;
|
|
43
46
|
|
|
@@ -1,29 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fromHono } from "chanfana";
|
|
2
|
+
import { Hono } from "hono";
|
|
2
3
|
import { TaskCreate } from "./endpoints/taskCreate";
|
|
3
4
|
import { TaskDelete } from "./endpoints/taskDelete";
|
|
4
5
|
import { TaskFetch } from "./endpoints/taskFetch";
|
|
5
6
|
import { TaskList } from "./endpoints/taskList";
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
// Start a Hono app
|
|
9
|
+
const app = new Hono();
|
|
10
|
+
|
|
11
|
+
// Setup OpenAPI registry
|
|
12
|
+
const openapi = fromHono(app, {
|
|
8
13
|
docs_url: "/",
|
|
9
14
|
});
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// 404 for everything else
|
|
17
|
-
router.all("*", () =>
|
|
18
|
-
Response.json(
|
|
19
|
-
{
|
|
20
|
-
success: false,
|
|
21
|
-
error: "Route not found",
|
|
22
|
-
},
|
|
23
|
-
{ status: 404 }
|
|
24
|
-
)
|
|
25
|
-
);
|
|
16
|
+
// Register OpenAPI endpoints
|
|
17
|
+
openapi.get("/api/tasks", TaskList);
|
|
18
|
+
openapi.post("/api/tasks", TaskCreate);
|
|
19
|
+
openapi.get("/api/tasks/:taskSlug", TaskFetch);
|
|
20
|
+
openapi.delete("/api/tasks/:taskSlug", TaskDelete);
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
} satisfies ExportedHandler;
|
|
22
|
+
// Export the Hono app
|
|
23
|
+
export default app;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { DateTime, Str } from "
|
|
1
|
+
import { DateTime, Str } from "chanfana";
|
|
2
|
+
import { z } from "zod";
|
|
2
3
|
|
|
3
|
-
export const Task = {
|
|
4
|
-
name:
|
|
5
|
-
slug:
|
|
6
|
-
description:
|
|
7
|
-
completed:
|
|
8
|
-
due_date:
|
|
9
|
-
};
|
|
4
|
+
export const Task = z.object({
|
|
5
|
+
name: Str({ example: "lorem" }),
|
|
6
|
+
slug: Str(),
|
|
7
|
+
description: Str({ required: false }),
|
|
8
|
+
completed: z.boolean().default(false),
|
|
9
|
+
due_date: DateTime(),
|
|
10
|
+
});
|