@nilejs/cli 0.0.1 → 0.0.2

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/index.js CHANGED
@@ -18,7 +18,7 @@ var writeFileSafe = async (filePath, content) => {
18
18
  await ensureDir(dirname(filePath));
19
19
  await writeFile(filePath, content, "utf-8");
20
20
  };
21
- var readFileContent = async (filePath) => {
21
+ var readFileContent = (filePath) => {
22
22
  return readFile(filePath, "utf-8");
23
23
  };
24
24
  var copyDir = async (src, dest) => {
@@ -49,14 +49,33 @@ var replaceInFile = async (filePath, replacements) => {
49
49
 
50
50
  // src/utils/log.ts
51
51
  import pc from "picocolors";
52
+ var brand = () => console.log(`
53
+ ${pc.bold(pc.cyan("~ Nile"))}
54
+ `);
55
+ var outro = () => console.log(pc.dim(`
56
+ Happy hacking. Let code flow like river Nile.
57
+ `));
52
58
  var success = (msg) => console.log(pc.green(` ✓ ${msg}`));
53
- var info = (msg) => console.log(pc.cyan(` ${msg}`));
54
59
  var warn = (msg) => console.log(pc.yellow(` ⚠ ${msg}`));
55
60
  var error = (msg) => console.error(pc.red(` ✗ ${msg}`));
56
- var header = (msg) => console.log(`
57
- ${pc.bold(msg)}
58
- `);
59
61
  var hint = (msg) => console.log(pc.dim(` ${msg}`));
62
+ var SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
63
+ var createSpinner = (msg) => {
64
+ let i = 0;
65
+ const stream = process.stdout;
66
+ const id = setInterval(() => {
67
+ const frame = SPINNER_FRAMES[i % SPINNER_FRAMES.length];
68
+ stream.write(`\r ${pc.cyan(frame)} ${msg}`);
69
+ i++;
70
+ }, 80);
71
+ return {
72
+ stop: (finalMsg) => {
73
+ clearInterval(id);
74
+ stream.write(`\r ${pc.green("✓")} ${finalMsg}
75
+ `);
76
+ }
77
+ };
78
+ };
60
79
 
61
80
  // src/commands/generate-action.ts
62
81
  var toCamelCase = (str) => str.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
@@ -92,7 +111,7 @@ var generateActionCommand = async (serviceName, actionName) => {
92
111
  const serviceDir = resolve(process.cwd(), "src/services", serviceName);
93
112
  if (!pathExists(serviceDir)) {
94
113
  error(`Service "${serviceName}" not found at src/services/${serviceName}/`);
95
- hint("Create the service first: nile generate service " + serviceName);
114
+ hint(`Create the service first: nile generate service ${serviceName}`);
96
115
  process.exit(1);
97
116
  }
98
117
  const actionFile = resolve(serviceDir, `${actionName}.ts`);
@@ -100,13 +119,15 @@ var generateActionCommand = async (serviceName, actionName) => {
100
119
  error(`Action file "${actionName}.ts" already exists in src/services/${serviceName}/`);
101
120
  process.exit(1);
102
121
  }
103
- header(`Generating action: ${serviceName}/${actionName}`);
122
+ brand();
123
+ const spinner = createSpinner(`Creating action ${actionName}...`);
104
124
  await writeFileSafe(actionFile, generateActionContent(actionName, serviceName));
105
- success(`Action created at src/services/${serviceName}/${actionName}.ts`);
125
+ spinner.stop(`Action created at src/services/${serviceName}/${actionName}.ts`);
106
126
  const camel = toCamelCase(actionName);
107
- header("Next steps:");
108
- hint("Import and register the action in your service config:");
127
+ console.log("");
128
+ hint("Register the action in your service config:");
109
129
  hint(` import { ${camel}Action } from "./${serviceName}/${actionName}";`);
130
+ outro();
110
131
  };
111
132
 
112
133
  // src/commands/generate-service.ts
@@ -114,7 +135,7 @@ import { resolve as resolve2 } from "node:path";
114
135
 
115
136
  // src/utils/prompt.ts
116
137
  import { createInterface } from "node:readline";
117
- var confirmPrompt = async (question, defaultYes = true) => {
138
+ var confirmPrompt = (question, defaultYes = true) => {
118
139
  const suffix = defaultYes ? "[Y/n]" : "[y/N]";
119
140
  const rl = createInterface({
120
141
  input: process.stdin,
@@ -225,25 +246,26 @@ var generateServiceCommand = async (serviceName) => {
225
246
  error(`Service "${serviceName}" already exists at src/services/${serviceName}/`);
226
247
  process.exit(1);
227
248
  }
228
- header(`Generating service: ${serviceName}`);
249
+ brand();
250
+ const spinner = createSpinner(`Creating service ${serviceName}...`);
229
251
  await ensureDir(serviceDir);
230
- info("Creating demo action...");
231
252
  await writeFileSafe(resolve2(serviceDir, "sample.ts"), generateActionContent2(serviceName));
232
- info("Creating barrel export...");
233
253
  await writeFileSafe(resolve2(serviceDir, "index.ts"), generateBarrelContent(serviceName));
234
- success(`Service "${serviceName}" created at src/services/${serviceName}/`);
254
+ spinner.stop(`Service created at src/services/${serviceName}/`);
235
255
  const configPath = resolve2(servicesDir, "services.config.ts");
236
256
  if (!pathExists(configPath)) {
237
257
  warn("Could not find services.config.ts");
238
- header("Add this to your services config:");
258
+ console.log("");
259
+ hint("Add this to your services config:");
239
260
  console.log(generateConfigSnippet(serviceName));
261
+ outro();
240
262
  return;
241
263
  }
242
264
  const shouldRegister = await confirmPrompt("Register this service in services.config.ts?");
243
265
  if (shouldRegister) {
244
266
  const registered = await autoRegisterService(configPath, serviceName);
245
267
  if (registered) {
246
- success("Service registered in services.config.ts");
268
+ success("Registered in services.config.ts");
247
269
  } else {
248
270
  warn("Could not auto-register. Add manually:");
249
271
  console.log(`
@@ -251,9 +273,11 @@ ${generateConfigSnippet(serviceName)}
251
273
  `);
252
274
  }
253
275
  } else {
254
- header("Add this to your services config:");
276
+ console.log("");
277
+ hint("Add this to your services config:");
255
278
  console.log(generateConfigSnippet(serviceName));
256
279
  }
280
+ outro();
257
281
  };
258
282
 
259
283
  // src/commands/new.ts
@@ -277,11 +301,10 @@ var newCommand = async (projectName) => {
277
301
  error(`Directory "${projectName}" already exists.`);
278
302
  process.exit(1);
279
303
  }
280
- header(`Creating project: ${projectName}`);
304
+ brand();
305
+ const spinner = createSpinner(`Creating ${projectName}...`);
281
306
  const templateDir = resolveTemplateDir();
282
- info("Copying project files...");
283
307
  await copyDir(templateDir, targetDir);
284
- info("Configuring project...");
285
308
  const allFiles = await getFilesRecursive(targetDir);
286
309
  const replacements = { "{{projectName}}": projectName };
287
310
  for (const filePath of allFiles) {
@@ -289,12 +312,14 @@ var newCommand = async (projectName) => {
289
312
  await replaceInFile(filePath, replacements);
290
313
  }
291
314
  }
292
- success(`Project "${projectName}" created.`);
293
- header("Next steps:");
294
- hint(`cd ${projectName}`);
315
+ spinner.stop("Project ready.");
316
+ success(`Created ${projectName}`);
317
+ console.log("");
318
+ hint("cd " + projectName);
295
319
  hint("bun install");
296
320
  hint("cp .env.example .env");
297
321
  hint("bun run dev");
322
+ outro();
298
323
  };
299
324
 
300
325
  // src/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nilejs/cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "CLI for scaffolding and generating Nile backend projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,7 +10,7 @@ cp .env.example .env
10
10
  bun run dev
11
11
  ```
12
12
 
13
- The server starts at `http://localhost:3000`. PGLite creates an embedded Postgres database automatically, no external database required.
13
+ The server starts at `http://localhost:8000`. PGLite creates an embedded Postgres database automatically, no external database required.
14
14
 
15
15
  ## Scripts
16
16
 
@@ -51,7 +51,7 @@ All requests go through a single POST endpoint. The `intent` field determines th
51
51
  ### Explore available services
52
52
 
53
53
  ```bash
54
- curl -X POST http://localhost:3000/api/services \
54
+ curl -X POST http://localhost:8000/api/services \
55
55
  -H "Content-Type: application/json" \
56
56
  -d '{"intent":"explore","service":"*","action":"*","payload":{}}'
57
57
  ```
@@ -59,7 +59,7 @@ curl -X POST http://localhost:3000/api/services \
59
59
  ### Execute an action
60
60
 
61
61
  ```bash
62
- curl -X POST http://localhost:3000/api/services \
62
+ curl -X POST http://localhost:8000/api/services \
63
63
  -H "Content-Type: application/json" \
64
64
  -d '{"intent":"execute","service":"tasks","action":"create","payload":{"title":"My first task"}}'
65
65
  ```
@@ -67,7 +67,7 @@ curl -X POST http://localhost:3000/api/services \
67
67
  ### Get action schemas
68
68
 
69
69
  ```bash
70
- curl -X POST http://localhost:3000/api/services \
70
+ curl -X POST http://localhost:8000/api/services \
71
71
  -H "Content-Type: application/json" \
72
72
  -d '{"intent":"schema","service":"tasks","action":"*","payload":{}}'
73
73
  ```
@@ -36,8 +36,8 @@ const server = createNileServer({
36
36
  rest: {
37
37
  baseUrl: "/api",
38
38
  host: "localhost",
39
- port: 3000,
40
- allowedOrigins: ["http://localhost:3000"],
39
+ port: 8000,
40
+ allowedOrigins: ["http://localhost:8000"],
41
41
  enableStatus: true,
42
42
  },
43
43
  onBoot: {
@@ -52,7 +52,7 @@ const server = createNileServer({
52
52
  });
53
53
 
54
54
  if (server.rest) {
55
- const port = server.config.rest?.port ?? 3000;
55
+ const port = server.config.rest?.port ?? 8000;
56
56
  const { fetch } = server.rest.app;
57
57
 
58
58
  Bun.serve({ port, fetch });