|
1 | | -# AdonisJS package starter kit |
| 1 | +# AdonisJS Stats |
2 | 2 |
|
3 | | -> A boilerplate for creating AdonisJS packages |
| 3 | +📈 Get insights about your AdonisJS project. |
4 | 4 |
|
5 | | -This repo provides you with a starting point for creating AdonisJS packages. Of course, you can create a package from scratch with your folder structure and workflow. However, using this starter kit can speed up the process, as you have fewer decisions to make. |
| 5 | +AdonisJS Stats analyzes your codebase and provides detailed statistics about your project's structure, including counts for classes, methods, lines of code, and routes. |
6 | 6 |
|
7 | | -## Setup |
| 7 | +## Installation |
8 | 8 |
|
9 | | -- Clone the repo on your computer, or use `giget` to download this repo without the Git history. |
10 | | - ```sh |
11 | | - npx giget@latest gh:adonisjs/pkg-starter-kit |
12 | | - ``` |
13 | | -- Install dependencies. |
14 | | -- Update the `package.json` file and define the `name`, `description`, `keywords`, and `author` properties. |
15 | | -- The repo is configured with an MIT license. Feel free to change that if you are not publishing under the MIT license. |
| 9 | +Install the package using npm or your preferred package manager: |
16 | 10 |
|
17 | | -## Folder structure |
| 11 | +```bash |
| 12 | +node ace add adonisjs-stats |
| 13 | +``` |
| 14 | + |
| 15 | +## Usage |
18 | 16 |
|
19 | | -The starter kit mimics the folder structure of the official packages. Feel free to rename files and folders as per your requirements. |
| 17 | +After installing, you can generate statistics by running the following Ace command: |
20 | 18 |
|
| 19 | +```bash |
| 20 | +node ace stats |
21 | 21 | ``` |
22 | | -├── providers |
23 | | -├── src |
24 | | -├── bin |
25 | | -├── stubs |
26 | | -├── configure.ts |
27 | | -├── index.ts |
28 | | -├── LICENSE.md |
29 | | -├── package.json |
30 | | -├── README.md |
31 | | -├── tsconfig.json |
32 | | -├── tsnode.esm.js |
| 22 | + |
| 23 | +The statistics are also available as JSON: |
| 24 | + |
| 25 | +```bash |
| 26 | +node ace stats --json |
33 | 27 | ``` |
34 | 28 |
|
35 | | -- The `configure.ts` file exports the `configure` hook to configure the package using the `node ace configure` command. |
36 | | -- The `index.ts` file is the main entry point of the package. |
37 | | -- The `tsnode.esm.js` file runs TypeScript code using TS-Node + SWC. Please read the code comment in this file to learn more. |
38 | | -- The `bin` directory contains the entry point file to run Japa tests. |
39 | | -- Learn more about [the `providers` directory](./providers/README.md). |
40 | | -- Learn more about [the `src` directory](./src/README.md). |
41 | | -- Learn more about [the `stubs` directory](./stubs/README.md). |
| 29 | +For a more detailed report showing which classes have been grouped into which component, use the `--verbose` option: |
42 | 30 |
|
43 | | -### File system naming convention |
| 31 | +```bash |
| 32 | +node ace stats --verbose |
| 33 | +``` |
44 | 34 |
|
45 | | -We use `snake_case` naming conventions for the file system. The rule is enforced using ESLint. However, turn off the rule and use your preferred naming conventions. |
| 35 | +The verbose option is available for the JSON format as well: |
46 | 36 |
|
47 | | -## Peer dependencies |
| 37 | +```bash |
| 38 | +node ace stats --json --verbose |
| 39 | +``` |
48 | 40 |
|
49 | | -The starter kit has a peer dependency on `@adonisjs/core@6`. Since you are creating a package for AdonisJS, you must make it against a specific version of the framework core. |
| 41 | +## Output Example |
50 | 42 |
|
51 | | -If your package needs Lucid to be functional, you may install `@adonisjs/lucid` as a development dependency and add it to the list of `peerDependencies`. |
| 43 | +``` |
| 44 | +Name | Classes | Methods | Methods/Class | LoC | LLoC | LLoC/Method |
| 45 | +--------------------|------------|------------|---------------|----------|----------|------------- |
| 46 | +Commands | 4 | 14 | 3.50 | 382 | 99 | 7.07 |
| 47 | +Controllers | 30 | 83 | 2.77 | 1483 | 486 | 5.86 |
| 48 | +Events | 3 | 7 | 2.33 | 175 | 60 | 8.57 |
| 49 | +Exceptions | 6 | 13 | 2.17 | 310 | 82 | 6.31 |
| 50 | +Listeners | 8 | 4 | 0.50 | 199 | 35 | 8.75 |
| 51 | +Middlewares | 47 | 94 | 2.00 | 1788 | 492 | 5.23 |
| 52 | +Models | 11 | 68 | 6.18 | 930 | 203 | 2.99 |
| 53 | +Services | 3 | 12 | 4.00 | 212 | 34 | 2.83 |
| 54 | +Tests | 6 | 36 | 6.00 | 533 | 65 | 1.81 |
| 55 | +Validators | 7 | 16 | 2.29 | 283 | 38 | 2.38 |
| 56 | +Other | 18 | 44 | 2.44 | 1421 | 382 | 8.68 |
| 57 | +Total | 203 | 602 | 2.97 | 11964 | 3359 | 5.58 |
| 58 | +
|
| 59 | +Code LLoC: 2088 • Test LLoC: 1271 • Code/Test Ratio: 1:0.6 • Routes: 169 |
| 60 | +``` |
52 | 61 |
|
53 | | -As a rule of thumb, packages installed in the user application should be part of the `peerDependencies` of your package and not the main dependency. |
| 62 | +## How does this package detect certain AdonisJS Components? |
54 | 63 |
|
55 | | -For example, if you install `@adonisjs/core` as a main dependency, then essentially, you are importing a separate copy of `@adonisjs/core` and not sharing the one from the user application. Here is a great article explaining [peer dependencies](https://blog.bitsrc.io/understanding-peer-dependencies-in-javascript-dbdb4ab5a7be). |
| 64 | +The package scans TypeScript files in your project using `ts-morph` and applies classifiers to determine which AdonisJS component each class represents. |
56 | 65 |
|
57 | | -## Published files |
| 66 | +| Component | Classification | |
| 67 | +|--------------|--------------------------------------------------------------------------------| |
| 68 | +| Controllers | Files in `app/controllers/` directory or files ending with `controller.ts` | |
| 69 | +| Services | Files in `app/services/` directory or files ending with `service.ts` | |
| 70 | +| Models | Files in `app/models/` directory or files ending with `model.ts` | |
| 71 | +| Middleware | Files in `app/middleware/` directory or files ending with `middleware.ts` | |
| 72 | +| Validators | Files in `app/validators/` directory or files ending with `validator.ts` | |
| 73 | +| Commands | Files in `app/commands/` directory or files ending with `command.ts` | |
| 74 | +| Listeners | Files in `app/listeners/` directory or files ending with `listener.ts` | |
| 75 | +| Events | Files in `app/events/` directory or files ending with `event.ts` | |
| 76 | +| Exceptions | Files in `app/exceptions/` directory or files ending with `exception.ts` | |
| 77 | +| Tests | Files in `tests/` directory or files ending with `.test.ts` or `.spec.ts` | |
58 | 78 |
|
59 | | -Instead of publishing your repo's source code to npm, you must cherry-pick files and folders to publish only the required files. |
| 79 | +## Configuration |
60 | 80 |
|
61 | | -The cherry-picking uses the `files` property inside the `package.json` file. By default, we publish the following files and folders. |
| 81 | +You can configure the package by publishing the config file: |
62 | 82 |
|
63 | | -```json |
64 | | -{ |
65 | | - "files": ["build/src", "build/providers", "build/stubs", "build/index.d.ts", "build/index.js", "build/configure.d.ts", "build/configure.js"] |
66 | | -} |
| 83 | +```bash |
| 84 | +node ace configure adonisjs-stats |
67 | 85 | ``` |
68 | 86 |
|
69 | | -If you create additional folders or files, mention them inside the `files` array. |
| 87 | +This will create a `config/stats.ts` file where you can customize the behavior: |
70 | 88 |
|
71 | | -## Exports |
| 89 | +```typescript |
| 90 | +import { defineConfig } from 'adonisjs-stats' |
72 | 91 |
|
73 | | -[Node.js Subpath exports](https://nodejs.org/api/packages.html#subpath-exports) allows you to define the exports of your package regardless of the folder structure. This starter kit defines the following exports. |
| 92 | +const statsConfig = defineConfig({ |
| 93 | + /** |
| 94 | + * Custom classifier classes (full import paths) |
| 95 | + * Example: ['#app/classifiers/custom_classifier'] |
| 96 | + */ |
| 97 | + customClassifiers: [] as string[], |
| 98 | +}) |
74 | 99 |
|
75 | | -```json |
76 | | -{ |
77 | | - "exports": { |
78 | | - ".": "./build/index.js", |
79 | | - "./types": "./build/src/types.js" |
80 | | - } |
81 | | -} |
| 100 | +export default statsConfig |
82 | 101 | ``` |
83 | 102 |
|
84 | | -- The dot `.` export is the main export. |
85 | | -- The `./types` exports all the types defined inside the `./build/src/types.js` file (the compiled output). |
| 103 | +## Create your own Classifiers |
| 104 | + |
| 105 | +If your application has its own components you would like to see in `adonisjs-stats`, you can create your own classifiers. Create a classifier by implementing the `Classifier` interface and adding it to the `customClassifiers` config array. |
86 | 106 |
|
87 | | -Feel free to change the exports as per your requirements. |
| 107 | +### Example: Repository Classifier |
88 | 108 |
|
89 | | -## Testing |
| 109 | +```typescript |
| 110 | +// app/classifiers/repository_classifier.ts |
| 111 | +import type { Classifier } from 'adonisjs-stats/types' |
| 112 | +import type { FileAnalysis } from 'adonisjs-stats/types' |
90 | 113 |
|
91 | | -We configure the [Japa test runner](https://japa.dev/) with this starter kit. Japa is used in AdonisJS applications as well. Just run one of the following commands to execute tests. |
| 114 | +export class RepositoryClassifier implements Classifier { |
| 115 | + name(): string { |
| 116 | + return 'Repositories' |
| 117 | + } |
| 118 | + |
| 119 | + satisfies(filePath: string, analysis: FileAnalysis): boolean { |
| 120 | + return ( |
| 121 | + (filePath.includes('/repositories/') || filePath.includes('\\repositories\\')) && |
| 122 | + analysis.className !== null |
| 123 | + ) |
| 124 | + } |
92 | 125 |
|
93 | | -- `npm run test`: This command will first lint the code using ESlint and then run tests and report the test coverage using [c8](https://github.com/bcoe/c8). |
94 | | -- `npm run quick:test`: Runs only the tests without linting or coverage reporting. |
| 126 | + countsTowardsApplicationCode(): boolean { |
| 127 | + return true |
| 128 | + } |
95 | 129 |
|
96 | | -The starter kit also has a Github workflow file to run tests using Github Actions. The tests are executed against `Node.js 20.x` and `Node.js 21.x` versions on both Linux and Windows. Feel free to edit the workflow file in the `.github/workflows` directory. |
| 130 | + countsTowardsTests(): boolean { |
| 131 | + return false |
| 132 | + } |
| 133 | +} |
| 134 | +``` |
97 | 135 |
|
98 | | -## TypeScript workflow |
| 136 | +Then add it to your config: |
99 | 137 |
|
100 | | -- The starter kit uses [tsc](https://www.typescriptlang.org/docs/handbook/compiler-options.html) for compiling the TypeScript to JavaScript when publishing the package. |
101 | | -- [TS-Node](https://typestrong.org/ts-node/) and [SWC](https://swc.rs/) are used to run tests without compiling the source code. |
102 | | -- The `tsconfig.json` file is extended from [`@adonisjs/tsconfig`](https://github.com/adonisjs/tooling-config/tree/main/packages/typescript-config) and uses the `NodeNext` module system. Meaning the packages are written using ES modules. |
103 | | -- You can perform type checking without compiling the source code using the `npm run type check` script. |
| 138 | +```typescript |
| 139 | +// config/stats.ts |
| 140 | +import { defineConfig } from 'adonisjs-stats' |
| 141 | +import { RepositoryClassifier } from '#app/classifiers/repository_classifier' |
104 | 142 |
|
105 | | -Feel free to explore the `tsconfig.json` file for all the configured options. |
| 143 | +const statsConfig = defineConfig({ |
| 144 | + customClassifiers: ['#app/classifiers/repository_classifier'], |
| 145 | +}) |
106 | 146 |
|
107 | | -## ESLint and Prettier setup |
| 147 | +export default statsConfig |
| 148 | +``` |
108 | 149 |
|
109 | | -The starter kit configures ESLint and Prettier |
110 | | -using our [shared config](https://github.com/adonisjs/tooling-config/tree/main/packages). |
111 | | -ESLint configuration is stored within the `eslint.config.js` file. |
112 | | -Prettier configuration is stored within the `package.json` file. |
113 | | -Feel free to change the configuration, use custom plugins, or remove both tools altogether. |
| 150 | +## Statistics Explained |
114 | 151 |
|
115 | | -## Using Stale bot |
| 152 | +- **Classes**: Number of class declarations found |
| 153 | +- **Methods**: Total number of methods in all classes |
| 154 | +- **Methods/Class**: Average number of methods per class |
| 155 | +- **LoC**: Lines of Code (total lines including comments and empty lines) |
| 156 | +- **LLoC**: Logical Lines of Code (excluding comments and empty lines) |
| 157 | +- **LLoC/Method**: Average logical lines of code per method |
| 158 | +- **Routes**: Total number of registered routes in your application |
116 | 159 |
|
117 | | -The [Stale bot](https://github.com/apps/stale) is a Github application that automatically marks issues and PRs as stale and closes after a specific duration of inactivity. |
| 160 | +## License |
118 | 161 |
|
119 | | -Feel free to delete the `.github/stale.yml` and `.github/lock.yml` files if you decide not to use the Stale bot. |
| 162 | +MIT |
0 commit comments