@nilejs/cli 0.0.7 → 1.0.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/README.md +56 -121
- package/dist/index.js +87 -58
- package/package.json +8 -6
- package/template/Dockerfile +1 -2
- package/template/README.md +33 -21
- package/template/SKILL.md +343 -0
- package/template/docker-compose.dev.yml +0 -1
- package/template/docker-compose.yml +4 -24
- package/template/gitignore +16 -0
- package/template/package.json +9 -8
- package/template/src/db/models/tasks.ts +2 -2
- package/template/src/index.ts +40 -9
- package/template/src/services/services.config.ts +3 -20
- package/template/src/services/tasks/{create.ts → actions/create.ts} +12 -8
- package/template/src/services/tasks/actions/delete.ts +27 -0
- package/template/src/services/tasks/{get.ts → actions/get.ts} +10 -6
- package/template/src/services/tasks/{list.ts → actions/list.ts} +5 -3
- package/template/src/services/tasks/{update.ts → actions/update.ts} +15 -8
- package/template/src/services/tasks/index.ts +18 -0
- package/template/tsconfig.json +17 -5
- package/template/src/services/tasks/delete.ts +0 -23
package/template/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { createLogger, createNileServer } from "@nilejs/nile";
|
|
1
|
+
import { createLogger, createNileServer, utils } from "@nilejs/nile";
|
|
2
2
|
import { sql } from "drizzle-orm";
|
|
3
|
-
import {
|
|
4
|
-
import { db } from "@/db/client";
|
|
3
|
+
import { Ok, safeTry } from "@nilejs/nile/fp";
|
|
4
|
+
import { db, pglite } from "@/db/client";
|
|
5
5
|
import { services } from "@/services/services.config";
|
|
6
6
|
|
|
7
7
|
const logger = createLogger("{{projectName}}", {
|
|
@@ -25,12 +25,22 @@ const pushSchema = async () => {
|
|
|
25
25
|
);
|
|
26
26
|
|
|
27
27
|
if (result.isErr) {
|
|
28
|
-
|
|
28
|
+
return utils.handleError({
|
|
29
|
+
message: "Could not prepare the task database.",
|
|
30
|
+
data: utils.describeError(result.raw),
|
|
31
|
+
atFunction: "pushSchema",
|
|
32
|
+
logger: logger,
|
|
33
|
+
});
|
|
29
34
|
}
|
|
35
|
+
|
|
36
|
+
return Ok(null);
|
|
30
37
|
};
|
|
31
38
|
|
|
32
39
|
const server = await createNileServer({
|
|
33
40
|
serverName: "{{projectName}}",
|
|
41
|
+
runtime: "bun",
|
|
42
|
+
native: true,
|
|
43
|
+
project: { root: process.cwd(), structure: "error" },
|
|
34
44
|
services,
|
|
35
45
|
resources: { logger, database: db },
|
|
36
46
|
rest: {
|
|
@@ -42,8 +52,13 @@ const server = await createNileServer({
|
|
|
42
52
|
discovery: { enabled: true },
|
|
43
53
|
},
|
|
44
54
|
onBoot: {
|
|
55
|
+
// The first PGlite start on a slow machine can take longer than the 10 second default.
|
|
56
|
+
maxWaitTime: 30_000,
|
|
45
57
|
fn: async (ctx) => {
|
|
46
|
-
await pushSchema();
|
|
58
|
+
const prepared = await pushSchema();
|
|
59
|
+
if (prepared.isErr) {
|
|
60
|
+
return prepared;
|
|
61
|
+
}
|
|
47
62
|
ctx.resources?.logger?.info({
|
|
48
63
|
atFunction: "onBoot",
|
|
49
64
|
message: "{{projectName}} booted - PGLite schema ready",
|
|
@@ -54,18 +69,34 @@ const server = await createNileServer({
|
|
|
54
69
|
});
|
|
55
70
|
|
|
56
71
|
// Register custom middleware (runs before all service requests)
|
|
57
|
-
server.
|
|
72
|
+
server.nativeRest?.addMiddleware("/api", async (c, next) => {
|
|
58
73
|
const start = performance.now();
|
|
59
74
|
await next();
|
|
60
75
|
const ms = (performance.now() - start).toFixed(1);
|
|
61
76
|
logger.info({
|
|
62
77
|
atFunction: "requestLog",
|
|
63
|
-
message: `${c.
|
|
78
|
+
message: `${c.request.method} ${c.path} - ${ms}ms`,
|
|
64
79
|
});
|
|
80
|
+
return undefined;
|
|
65
81
|
});
|
|
66
82
|
|
|
67
|
-
if (server.
|
|
83
|
+
if (server.nativeRest) {
|
|
68
84
|
const port = server.config.rest?.port ?? 8000;
|
|
69
|
-
Bun.serve({
|
|
85
|
+
const listener = Bun.serve({
|
|
86
|
+
port: port,
|
|
87
|
+
fetch: server.nativeRest.fetch,
|
|
88
|
+
});
|
|
89
|
+
let closing = false;
|
|
90
|
+
const shutdown = async () => {
|
|
91
|
+
if (closing) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
closing = true;
|
|
95
|
+
listener.stop();
|
|
96
|
+
await server.lifecycle.shutdown();
|
|
97
|
+
await pglite.close();
|
|
98
|
+
};
|
|
99
|
+
process.once("SIGINT", shutdown);
|
|
100
|
+
process.once("SIGTERM", shutdown);
|
|
70
101
|
console.log(`\n{{projectName}} listening on http://localhost:${port}\n`);
|
|
71
102
|
}
|
|
@@ -1,21 +1,4 @@
|
|
|
1
|
-
import { createServices
|
|
2
|
-
import {
|
|
3
|
-
import { deleteTaskAction } from "./tasks/delete";
|
|
4
|
-
import { getTaskAction } from "./tasks/get";
|
|
5
|
-
import { listTaskAction } from "./tasks/list";
|
|
6
|
-
import { updateTaskAction } from "./tasks/update";
|
|
1
|
+
import { createServices } from "@nilejs/nile";
|
|
2
|
+
import { tasksService } from "./tasks";
|
|
7
3
|
|
|
8
|
-
export const services
|
|
9
|
-
{
|
|
10
|
-
name: "tasks",
|
|
11
|
-
description: "Task management with CRUD operations",
|
|
12
|
-
meta: { version: "1.0.0" },
|
|
13
|
-
actions: [
|
|
14
|
-
createTaskAction,
|
|
15
|
-
listTaskAction,
|
|
16
|
-
getTaskAction,
|
|
17
|
-
updateTaskAction,
|
|
18
|
-
deleteTaskAction,
|
|
19
|
-
],
|
|
20
|
-
},
|
|
21
|
-
]);
|
|
4
|
+
export const services = createServices([tasksService]);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Err, Ok } from "
|
|
1
|
+
import { createAction } from "@nilejs/nile";
|
|
2
|
+
import { Err, Ok } from "@nilejs/nile/fp";
|
|
3
3
|
import z from "zod";
|
|
4
4
|
import { taskModel } from "@/db/models";
|
|
5
5
|
|
|
@@ -12,23 +12,27 @@ const createTaskSchema = z.object({
|
|
|
12
12
|
.default("pending"),
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
type CreateTaskInput = z.infer<typeof createTaskSchema>;
|
|
16
|
+
|
|
17
|
+
const createTaskHandler = async (input: CreateTaskInput) => {
|
|
16
18
|
const result = await taskModel.create({
|
|
17
19
|
data: {
|
|
18
|
-
title:
|
|
19
|
-
description:
|
|
20
|
-
status:
|
|
20
|
+
title: input.title,
|
|
21
|
+
description: input.description,
|
|
22
|
+
status: input.status,
|
|
21
23
|
},
|
|
22
24
|
});
|
|
25
|
+
|
|
23
26
|
if (result.isErr) {
|
|
24
27
|
return Err(result.error);
|
|
25
28
|
}
|
|
29
|
+
|
|
26
30
|
return Ok({ task: result.value });
|
|
27
31
|
};
|
|
28
32
|
|
|
29
|
-
export const createTaskAction
|
|
33
|
+
export const createTaskAction = createAction<CreateTaskInput>({
|
|
30
34
|
name: "create",
|
|
31
35
|
description: "Create a new task",
|
|
32
|
-
handler: createTaskHandler,
|
|
33
36
|
validation: createTaskSchema,
|
|
37
|
+
handler: createTaskHandler,
|
|
34
38
|
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createAction } from "@nilejs/nile";
|
|
2
|
+
import { Err, Ok } from "@nilejs/nile/fp";
|
|
3
|
+
import z from "zod";
|
|
4
|
+
import { taskModel } from "@/db/models";
|
|
5
|
+
|
|
6
|
+
const deleteTaskSchema = z.object({
|
|
7
|
+
id: z.string().min(1, "Task ID is required"),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
type DeleteTaskInput = z.infer<typeof deleteTaskSchema>;
|
|
11
|
+
|
|
12
|
+
const deleteTaskHandler = async (input: DeleteTaskInput) => {
|
|
13
|
+
const result = await taskModel.delete(input.id);
|
|
14
|
+
|
|
15
|
+
if (result.isErr) {
|
|
16
|
+
return Err(result.error);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return Ok({ deleted: true, id: input.id });
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const deleteTaskAction = createAction<DeleteTaskInput>({
|
|
23
|
+
name: "delete",
|
|
24
|
+
description: "Delete a task by ID",
|
|
25
|
+
validation: deleteTaskSchema,
|
|
26
|
+
handler: deleteTaskHandler,
|
|
27
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Err, Ok } from "
|
|
1
|
+
import { createAction } from "@nilejs/nile";
|
|
2
|
+
import { Err, Ok } from "@nilejs/nile/fp";
|
|
3
3
|
import z from "zod";
|
|
4
4
|
import { taskModel } from "@/db/models";
|
|
5
5
|
|
|
@@ -7,17 +7,21 @@ const getTaskSchema = z.object({
|
|
|
7
7
|
id: z.string().min(1, "Task ID is required"),
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
type GetTaskInput = z.infer<typeof getTaskSchema>;
|
|
11
|
+
|
|
12
|
+
const getTaskHandler = async (input: GetTaskInput) => {
|
|
13
|
+
const result = await taskModel.findById(input.id);
|
|
14
|
+
|
|
12
15
|
if (result.isErr) {
|
|
13
16
|
return Err(result.error);
|
|
14
17
|
}
|
|
18
|
+
|
|
15
19
|
return Ok({ task: result.value });
|
|
16
20
|
};
|
|
17
21
|
|
|
18
|
-
export const getTaskAction
|
|
22
|
+
export const getTaskAction = createAction<GetTaskInput>({
|
|
19
23
|
name: "get",
|
|
20
24
|
description: "Get a task by ID",
|
|
21
|
-
handler: getTaskHandler,
|
|
22
25
|
validation: getTaskSchema,
|
|
26
|
+
handler: getTaskHandler,
|
|
23
27
|
});
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Err, Ok } from "
|
|
1
|
+
import { createAction } from "@nilejs/nile";
|
|
2
|
+
import { Err, Ok } from "@nilejs/nile/fp";
|
|
3
3
|
import { taskModel } from "@/db/models";
|
|
4
4
|
|
|
5
5
|
const listTasksHandler = async () => {
|
|
6
6
|
const result = await taskModel.findAll();
|
|
7
|
+
|
|
7
8
|
if (result.isErr) {
|
|
8
9
|
return Err(result.error);
|
|
9
10
|
}
|
|
11
|
+
|
|
10
12
|
return Ok({ tasks: result.value });
|
|
11
13
|
};
|
|
12
14
|
|
|
13
|
-
export const listTaskAction
|
|
15
|
+
export const listTaskAction = createAction({
|
|
14
16
|
name: "list",
|
|
15
17
|
description: "List all tasks",
|
|
16
18
|
handler: listTasksHandler,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Err, Ok } from "
|
|
1
|
+
import { createAction } from "@nilejs/nile";
|
|
2
|
+
import { Err, Ok } from "@nilejs/nile/fp";
|
|
3
3
|
import z from "zod";
|
|
4
4
|
import { taskModel } from "@/db/models";
|
|
5
5
|
|
|
@@ -10,22 +10,29 @@ const updateTaskSchema = z.object({
|
|
|
10
10
|
status: z.enum(["pending", "in-progress", "done"]).optional(),
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
const { id, ...updates } = data;
|
|
13
|
+
type UpdateTaskInput = z.infer<typeof updateTaskSchema>;
|
|
15
14
|
|
|
15
|
+
const updateTaskHandler = async (input: UpdateTaskInput) => {
|
|
16
|
+
// Fields left out of the request stay undefined and are not changed.
|
|
16
17
|
const result = await taskModel.update({
|
|
17
|
-
id: id
|
|
18
|
-
data:
|
|
18
|
+
id: input.id,
|
|
19
|
+
data: {
|
|
20
|
+
title: input.title,
|
|
21
|
+
description: input.description,
|
|
22
|
+
status: input.status,
|
|
23
|
+
},
|
|
19
24
|
});
|
|
25
|
+
|
|
20
26
|
if (result.isErr) {
|
|
21
27
|
return Err(result.error);
|
|
22
28
|
}
|
|
29
|
+
|
|
23
30
|
return Ok({ task: result.value });
|
|
24
31
|
};
|
|
25
32
|
|
|
26
|
-
export const updateTaskAction
|
|
33
|
+
export const updateTaskAction = createAction<UpdateTaskInput>({
|
|
27
34
|
name: "update",
|
|
28
35
|
description: "Update an existing task",
|
|
29
|
-
handler: updateTaskHandler,
|
|
30
36
|
validation: updateTaskSchema,
|
|
37
|
+
handler: updateTaskHandler,
|
|
31
38
|
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createService } from "@nilejs/nile";
|
|
2
|
+
import { createTaskAction } from "./actions/create";
|
|
3
|
+
import { deleteTaskAction } from "./actions/delete";
|
|
4
|
+
import { getTaskAction } from "./actions/get";
|
|
5
|
+
import { listTaskAction } from "./actions/list";
|
|
6
|
+
import { updateTaskAction } from "./actions/update";
|
|
7
|
+
|
|
8
|
+
export const tasksService = createService({
|
|
9
|
+
name: "tasks",
|
|
10
|
+
description: "Task management with CRUD operations",
|
|
11
|
+
actions: [
|
|
12
|
+
createTaskAction,
|
|
13
|
+
listTaskAction,
|
|
14
|
+
getTaskAction,
|
|
15
|
+
updateTaskAction,
|
|
16
|
+
deleteTaskAction,
|
|
17
|
+
],
|
|
18
|
+
});
|
package/template/tsconfig.json
CHANGED
|
@@ -8,11 +8,23 @@
|
|
|
8
8
|
"skipLibCheck": true,
|
|
9
9
|
"outDir": "./dist",
|
|
10
10
|
"rootDir": ".",
|
|
11
|
-
"baseUrl": ".",
|
|
12
11
|
"paths": {
|
|
13
|
-
"@/*": [
|
|
14
|
-
|
|
12
|
+
"@/*": [
|
|
13
|
+
"./src/*"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"types": [
|
|
18
|
+
"bun"
|
|
19
|
+
]
|
|
15
20
|
},
|
|
16
|
-
"include": [
|
|
17
|
-
|
|
21
|
+
"include": [
|
|
22
|
+
"./src/**/*.ts",
|
|
23
|
+
"./drizzle.config.ts"
|
|
24
|
+
],
|
|
25
|
+
"exclude": [
|
|
26
|
+
"node_modules",
|
|
27
|
+
"dist",
|
|
28
|
+
"data"
|
|
29
|
+
]
|
|
18
30
|
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { type Action, createAction } from "@nilejs/nile";
|
|
2
|
-
import { Err, Ok } from "slang-ts";
|
|
3
|
-
import z from "zod";
|
|
4
|
-
import { taskModel } from "@/db/models";
|
|
5
|
-
|
|
6
|
-
const deleteTaskSchema = z.object({
|
|
7
|
-
id: z.string().min(1, "Task ID is required"),
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
const deleteTaskHandler = async (data: Record<string, unknown>) => {
|
|
11
|
-
const result = await taskModel.delete(data.id as string);
|
|
12
|
-
if (result.isErr) {
|
|
13
|
-
return Err(result.error);
|
|
14
|
-
}
|
|
15
|
-
return Ok({ deleted: true, id: data.id });
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export const deleteTaskAction: Action = createAction({
|
|
19
|
-
name: "delete",
|
|
20
|
-
description: "Delete a task by ID",
|
|
21
|
-
handler: deleteTaskHandler,
|
|
22
|
-
validation: deleteTaskSchema,
|
|
23
|
-
});
|