@aponiajs/cli 0.3.19 → 0.3.21

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.mjs CHANGED
@@ -1,14 +1,11 @@
1
1
  import { camelCase, kebabCase, pascalCase } from "change-case";
2
2
  import parseCliArguments from "yargs-parser";
3
- import { mkdir, readdir } from "node:fs/promises";
3
+ import { lstat, mkdir, readdir, rm } from "node:fs/promises";
4
4
  import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import findFiles from "fast-glob";
7
7
  import { singularize } from "inflection";
8
8
  import { IndentationText, Node, Project, QuoteKind, SyntaxKind } from "ts-morph";
9
- //#region package.json
10
- var version = "0.3.19";
11
- //#endregion
12
9
  //#region src/arguments.ts
13
10
  const generateSchematics = [
14
11
  "app",
@@ -185,6 +182,9 @@ function readStringOption(options, name) {
185
182
  return value;
186
183
  }
187
184
  //#endregion
185
+ //#region src/version.ts
186
+ const aponiaVersion = "0.3.21";
187
+ //#endregion
188
188
  //#region src/project-generator.ts
189
189
  const projectNamePattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
190
190
  async function generateProject(options) {
@@ -192,38 +192,48 @@ async function generateProject(options) {
192
192
  const projectDirectory = join(options.cwd ?? process.cwd(), options.name);
193
193
  const templateDirectory = fileURLToPath(new URL("../templates/application", import.meta.url));
194
194
  const templateFiles = await listFiles(templateDirectory);
195
- const relativeFiles = templateFiles.map((file) => outputPath(relative(templateDirectory, file)));
195
+ const relativeFiles = templateFiles.map((file) => outputPath(relative(templateDirectory, file))).toSorted();
196
196
  if (options.dryRun) return {
197
197
  projectDirectory,
198
198
  files: relativeFiles,
199
199
  installed: false,
200
200
  dryRun: true
201
201
  };
202
- if (await Bun.file(projectDirectory).exists()) throw new Error(`Target directory "${basename(projectDirectory)}" already exists.`);
202
+ if (await pathExists(projectDirectory)) throw new Error(`Target directory "${basename(projectDirectory)}" already exists.`);
203
203
  await mkdir(projectDirectory, { recursive: false });
204
- for (const templateFile of templateFiles) {
205
- const outputFile = join(projectDirectory, outputPath(relative(templateDirectory, templateFile)));
206
- const output = (await Bun.file(templateFile).text()).replaceAll("{{PROJECT_NAME}}", options.name);
207
- await mkdir(dirname(outputFile), { recursive: true });
208
- await Bun.write(outputFile, output);
209
- }
210
- const shouldInstall = !options.skipInstall;
211
- if (shouldInstall) {
212
- const exitCode = await Bun.spawn(["bun", "install"], {
213
- cwd: projectDirectory,
214
- stdin: "inherit",
215
- stdout: "inherit",
216
- stderr: "inherit"
217
- }).exited;
218
- if (exitCode !== 0) throw new Error(`Bun install failed with exit code ${exitCode}.`);
204
+ try {
205
+ for (const templateFile of templateFiles) {
206
+ const outputFile = join(projectDirectory, outputPath(relative(templateDirectory, templateFile)));
207
+ const output = renderTemplate(await Bun.file(templateFile).text(), options.name);
208
+ await mkdir(dirname(outputFile), { recursive: true });
209
+ await Bun.write(outputFile, output);
210
+ }
211
+ if (!options.skipInstall) {
212
+ const exitCode = await Bun.spawn(["bun", "install"], {
213
+ cwd: projectDirectory,
214
+ stdin: "inherit",
215
+ stdout: "inherit",
216
+ stderr: "inherit"
217
+ }).exited;
218
+ if (exitCode !== 0) throw new Error(`Bun install failed with exit code ${exitCode}.`);
219
+ }
220
+ } catch (error) {
221
+ await rm(projectDirectory, {
222
+ recursive: true,
223
+ force: true
224
+ });
225
+ throw error;
219
226
  }
220
227
  return {
221
228
  projectDirectory,
222
229
  files: relativeFiles,
223
- installed: shouldInstall,
230
+ installed: !options.skipInstall,
224
231
  dryRun: false
225
232
  };
226
233
  }
234
+ function renderTemplate(template, projectName) {
235
+ return template.replaceAll("{{PROJECT_NAME}}", projectName).replaceAll("{{APONIA_VERSION}}", aponiaVersion);
236
+ }
227
237
  function outputPath(templatePath) {
228
238
  if (templatePath === "_gitignore") return ".gitignore";
229
239
  return templatePath.endsWith(".tmpl") ? templatePath.slice(0, -5) : templatePath;
@@ -238,6 +248,15 @@ async function listFiles(directory) {
238
248
  return entry.isDirectory() ? listFiles(path) : [path];
239
249
  }))).flat();
240
250
  }
251
+ async function pathExists(path) {
252
+ try {
253
+ await lstat(path);
254
+ return true;
255
+ } catch (error) {
256
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") return false;
257
+ throw error;
258
+ }
259
+ }
241
260
  //#endregion
242
261
  //#region src/component-names.ts
243
262
  function createComponentNames(input) {
@@ -487,7 +506,7 @@ async function generateLibrary(projectRoot, names, options) {
487
506
  build: "bun build ./src/index.ts --outdir ./dist --target bun",
488
507
  test: "bun test"
489
508
  },
490
- dependencies: { "@aponiajs/common": "latest" }
509
+ dependencies: { "@aponiajs/common": aponiaVersion }
491
510
  }, void 0, 2)}\n`),
492
511
  createFile(join(directory, "src"), `${names.fileName}.module.ts`, `import { Module } from "@aponiajs/common";\n\n@Module({})\nexport class ${names.className}Module {}\n`),
493
512
  createFile(join(directory, "src"), `${names.fileName}.service.ts`, `import { Injectable } from "@aponiajs/common";\n\n@Injectable()\nexport class ${names.className}Service {}\n`),
@@ -672,7 +691,7 @@ async function runCli(arguments_) {
672
691
  return 0;
673
692
  }
674
693
  if (command.command === "version") {
675
- console.log(version);
694
+ console.log(aponiaVersion);
676
695
  return 0;
677
696
  }
678
697
  if (command.command === "generate") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aponiajs/cli",
3
- "version": "0.3.19",
3
+ "version": "0.3.21",
4
4
  "description": "Bun-native project generator and command-line interface for Aponia.",
5
5
  "homepage": "https://github.com/aponiajs/aponiajs#readme",
6
6
  "bugs": {
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
- import cliManifest from "../package.json" with { type: "json" };
2
1
  import { parseArguments } from "./arguments.ts";
3
2
  import { generateProject } from "./project-generator.ts";
4
3
  import { generateSchematic } from "./schematic-generator.ts";
4
+ import { aponiaVersion } from "./version.ts";
5
5
 
6
6
  export {
7
7
  generateSchematics,
@@ -33,7 +33,7 @@ export async function runCli(arguments_: readonly string[]): Promise<number> {
33
33
  }
34
34
 
35
35
  if (command.command === "version") {
36
- console.log(cliManifest.version);
36
+ console.log(aponiaVersion);
37
37
  return 0;
38
38
  }
39
39
 
@@ -1,6 +1,7 @@
1
- import { mkdir, readdir } from "node:fs/promises";
1
+ import { lstat, mkdir, readdir, rm } from "node:fs/promises";
2
2
  import { basename, dirname, join, relative } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
+ import { aponiaVersion } from "./version.ts";
4
5
 
5
6
  export interface GenerateProjectOptions {
6
7
  readonly name: string;
@@ -27,7 +28,9 @@ export async function generateProject(
27
28
  const projectDirectory = join(workingDirectory, options.name);
28
29
  const templateDirectory = fileURLToPath(new URL("../templates/application", import.meta.url));
29
30
  const templateFiles = await listFiles(templateDirectory);
30
- const relativeFiles = templateFiles.map((file) => outputPath(relative(templateDirectory, file)));
31
+ const relativeFiles = templateFiles
32
+ .map((file) => outputPath(relative(templateDirectory, file)))
33
+ .toSorted();
31
34
 
32
35
  if (options.dryRun) {
33
36
  return {
@@ -38,43 +41,54 @@ export async function generateProject(
38
41
  };
39
42
  }
40
43
 
41
- if (await Bun.file(projectDirectory).exists()) {
44
+ if (await pathExists(projectDirectory)) {
42
45
  throw new Error(`Target directory "${basename(projectDirectory)}" already exists.`);
43
46
  }
44
47
 
45
48
  await mkdir(projectDirectory, { recursive: false });
46
- for (const templateFile of templateFiles) {
47
- const relativeFile = outputPath(relative(templateDirectory, templateFile));
48
- const outputFile = join(projectDirectory, relativeFile);
49
- const template = await Bun.file(templateFile).text();
50
- const output = template.replaceAll("{{PROJECT_NAME}}", options.name);
51
-
52
- await mkdir(dirname(outputFile), { recursive: true });
53
- await Bun.write(outputFile, output);
54
- }
49
+ try {
50
+ for (const templateFile of templateFiles) {
51
+ const relativeFile = outputPath(relative(templateDirectory, templateFile));
52
+ const outputFile = join(projectDirectory, relativeFile);
53
+ const template = await Bun.file(templateFile).text();
54
+ const output = renderTemplate(template, options.name);
55
+
56
+ await mkdir(dirname(outputFile), { recursive: true });
57
+ await Bun.write(outputFile, output);
58
+ }
55
59
 
56
- const shouldInstall = !options.skipInstall;
57
- if (shouldInstall) {
58
- const process = Bun.spawn(["bun", "install"], {
59
- cwd: projectDirectory,
60
- stdin: "inherit",
61
- stdout: "inherit",
62
- stderr: "inherit",
63
- });
64
- const exitCode = await process.exited;
65
- if (exitCode !== 0) {
66
- throw new Error(`Bun install failed with exit code ${exitCode}.`);
60
+ if (!options.skipInstall) {
61
+ const process = Bun.spawn(["bun", "install"], {
62
+ cwd: projectDirectory,
63
+ stdin: "inherit",
64
+ stdout: "inherit",
65
+ stderr: "inherit",
66
+ });
67
+ const exitCode = await process.exited;
68
+ if (exitCode !== 0) {
69
+ throw new Error(`Bun install failed with exit code ${exitCode}.`);
70
+ }
67
71
  }
72
+ } catch (error) {
73
+ await rm(projectDirectory, { recursive: true, force: true });
74
+ throw error;
68
75
  }
69
76
 
77
+ const installed = !options.skipInstall;
70
78
  return {
71
79
  projectDirectory,
72
80
  files: relativeFiles,
73
- installed: shouldInstall,
81
+ installed,
74
82
  dryRun: false,
75
83
  };
76
84
  }
77
85
 
86
+ function renderTemplate(template: string, projectName: string): string {
87
+ return template
88
+ .replaceAll("{{PROJECT_NAME}}", projectName)
89
+ .replaceAll("{{APONIA_VERSION}}", aponiaVersion);
90
+ }
91
+
78
92
  function outputPath(templatePath: string): string {
79
93
  if (templatePath === "_gitignore") {
80
94
  return ".gitignore";
@@ -102,3 +116,15 @@ async function listFiles(directory: string): Promise<string[]> {
102
116
 
103
117
  return files.flat();
104
118
  }
119
+
120
+ async function pathExists(path: string): Promise<boolean> {
121
+ try {
122
+ await lstat(path);
123
+ return true;
124
+ } catch (error) {
125
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
126
+ return false;
127
+ }
128
+ throw error;
129
+ }
130
+ }
@@ -10,6 +10,7 @@ import {
10
10
  } from "./component-names.ts";
11
11
  import { registerInModule, type ModuleRegistrationKind } from "./module-registration.ts";
12
12
  import { generateProject } from "./project-generator.ts";
13
+ import { aponiaVersion } from "./version.ts";
13
14
 
14
15
  export interface GenerateSchematicOptions extends GenerateCommandOptions {
15
16
  readonly cwd?: string;
@@ -310,7 +311,7 @@ async function generateLibrary(
310
311
  test: "bun test",
311
312
  },
312
313
  dependencies: {
313
- "@aponiajs/common": "latest",
314
+ "@aponiajs/common": aponiaVersion,
314
315
  },
315
316
  },
316
317
  undefined,
package/src/version.ts ADDED
@@ -0,0 +1,3 @@
1
+ import cliManifest from "../package.json" with { type: "json" };
2
+
3
+ export const aponiaVersion = cliManifest.version;
@@ -12,9 +12,8 @@
12
12
  "check": "vp check"
13
13
  },
14
14
  "dependencies": {
15
- "@aponiajs/common": "latest",
16
- "@aponiajs/core": "latest",
17
- "@aponiajs/platform-elysia": "latest",
15
+ "@aponiajs/common": "{{APONIA_VERSION}}",
16
+ "@aponiajs/platform-elysia": "{{APONIA_VERSION}}",
18
17
  "elysia": "^1.4.29"
19
18
  },
20
19
  "devDependencies": {