1 |
|
2 |
|
3 |
|
4 | # Installation
|
5 | ### Run CLI command from eveywhere
|
6 | Install `component-creator-cli` as **global dependency**
|
7 | ```bash
|
8 | npm i -g component-creator-cli
|
9 | ```
|
10 | - For run any command use : **`$ ccc`** keyword
|
11 |
|
12 | ### Run CLI command from your project
|
13 | Install `component-creator-cli` as **dev-dependency**
|
14 | ```bash
|
15 | npm i -D component-creator-cli
|
16 | ```
|
17 | - For run any command use : **`$ ngx ccc`** keyword
|
18 |
|
19 |
|
20 |
|
21 | # Component creator CLI
|
22 |
|
23 | [![NPM Version](http://img.shields.io/npm/v/component-creator-cli.svg)](https://www.npmjs.org/package/component-creator-cli)
|
24 | [![NPM Downloads](https://img.shields.io/npm/dm/component-creator-cli.svg)](https://npmcharts.com/compare/component-creator-cli?minimal=true)
|
25 | [![Install Size](https://packagephobia.now.sh/badge?p=component-creator-cli)](https://packagephobia.now.sh/result?p=component-creator-cli)
|
26 | ![Issues](https://img.shields.io/github/issues/enzo-cora/component-creator-cli.svg) [![Licence](https://img.shields.io/apm/l/atomic-design-ui.svg?)](https://github.com/tterb/atomic-design-ui/blob/master/LICENSEs)
|
27 |
|
28 | Are you interested in the **architecture of your project**?
|
29 | Do you do Domain Driven Design (DDD), Clean Architecture, React or simply MVC?
|
30 | If YES, then you will probably generate a project with repeating components that will have the same file structure.
|
31 | And you will reuse these paterns throughout the construction of your project architecture. (And even after) !
|
32 |
|
33 | Therefore, in order to save time on the creation of your architecture and improve your workflow, you can use "Component creator CLI" to generate your personalized component in 1 second! (via the command line)
|
34 |
|
35 | **1- Create your custom generic template
|
36 | 2- And run the CLI `generate` command to generate your component at the chosen locations.** (It's like the Angular CLI, with your own custom components !)
|
37 |
|
38 |
|
39 | ## I- CLI Features
|
40 |
|
41 | | # | Meaning |
|
42 | |----------------------------------------------------------|-----------------|
|
43 | | ![#0a192f](https://via.placeholder.com/10/00A000?text=+) | Implemented |
|
44 | | ![#f8f8f8](https://via.placeholder.com/10/e71837?text=+) | Not yet Implemented |
|
45 |
|
46 |
|
47 | - ![green](https://via.placeholder.com/10/00A000?text=+) `Create your custom template`
|
48 | - ![green](https://via.placeholder.com/10/00A000?text=+) `Define the files created by the template`
|
49 | - ![green](https://via.placeholder.com/10/00A000?text=+) `Define the files content`
|
50 | - ![green](https://via.placeholder.com/10/00A000?text=+) `Place the generic replacement keyword`
|
51 | - ![green](https://via.placeholder.com/10/00A000?text=+)`Choose the formatting convention for your generic keyword`
|
52 | - ![green](https://via.placeholder.com/10/00A000?text=+) `Configure component work directory target`
|
53 | - ![green](https://via.placeholder.com/10/00A000?text=+) `Configure component work directory extension`
|
54 | - ![green](https://via.placeholder.com/10/00A000?text=+) `Generate your own custom component`
|
55 | - ![green](https://via.placeholder.com/10/00A000?text=+) `Automatically Replace generic keyword`
|
56 | - ![green](https://via.placeholder.com/10/00A000?text=+) `Automatically Formate generic keyword`
|
57 | - ![green](https://via.placeholder.com/10/00A000?text=+) `Automatically Handle import path`
|
58 | - ![red](https://via.placeholder.com/10/e71837?text=+) `Delete created component`
|
59 | - ![green](https://via.placeholder.com/10/00A000?text=+) `List all template available`
|
60 | - ![green](https://via.placeholder.com/10/00A000?text=+) `Generate an example template`
|
61 |
|
62 |
|
63 | ## II- CLI Demo
|
64 |
|
65 | Gif incomming
|
66 | ![Demo animation cli](https://github.com/enzo-cora/component-creator-cli/blob/images/create-component.png?raw=true)
|
67 |
|
68 | ### A- Create component
|
69 | These 3 commands are the same :
|
70 | ```cmd
|
71 | $ ccc generate extravagant order
|
72 | $ ccc g extravagant user
|
73 | $ ngx ccc generate smartphone
|
74 | ```
|
75 |
|
76 | These commands will generate three components based on a custom "extravagant" template.
|
77 | The creation location is configured upstream (in the [template config file](#b--template-config-file-properties) ).
|
78 | Here are the generated components :
|
79 | ```
|
80 | FancifulEntities/
|
81 | ├─ my-extravagant-order/
|
82 | │ ├─ interfce-order.ts
|
83 | │ ├─ show-order-formated.html
|
84 | │ ├─ order-beauty.css
|
85 | │ ├─ test-my-order-please.test.ts
|
86 | │ └─ order.js
|
87 | │
|
88 | ├─ my-extravagant-user/
|
89 | │ ├─ interfce-user.ts
|
90 | │ ├─ show-user-formated.html
|
91 | │ ├─ user-beauty.css
|
92 | │ ├─ test-my-user-please.test.ts
|
93 | │ └─ user.js
|
94 | │
|
95 | ├─ my-extravagant-smartphone/
|
96 | │ ├─ interfce-smartphone.ts
|
97 | │ ├─ show-smartphone-formated.html
|
98 | │ ├─ smartphone-beauty.css
|
99 | │ ├─ test-my-smartphone-please.test.ts
|
100 | │ └─ smartphone.js
|
101 |
|
102 | ```
|
103 | See [more examples there](#examples)
|
104 |
|
105 | ## III- CLI Reference
|
106 |
|
107 | **Definitions**:
|
108 | - **Template** : A template is a way of writing an entity with some information “left generic”, for the CLI to fill in later, when we actually use it.
|
109 | - **Component** : A component is built version of a template
|
110 |
|
111 | ### A- Init CLI
|
112 |
|
113 | ```cmd
|
114 | $ ccc init
|
115 | ```
|
116 | This command initializes the CLI :
|
117 | - If this is the first use : it create config dir and an example template.
|
118 | - Otherwise, it checks the validity of existing templates and updates the cache.
|
119 |
|
120 | ### B- Create component
|
121 |
|
122 | ```cmd
|
123 | $ ccc generate <template-name> <replacement-value> [options]
|
124 | ```
|
125 | ```cmd
|
126 | $ ccc generate <template-name> <replacement-value> [options]
|
127 | ```
|
128 | This command will generate component based on [template](#v--template-structure).
|
129 |
|
130 | #### Arguments : `generate`
|
131 | | Argument | Type | Description |
|
132 | |:-----------------:|:------:|:--------------------------------------------------------------------------------:|
|
133 | | `<template-name>` | `string` | **Required**. Name of template to use. |
|
134 | | `<replacement-value>` | `string` | **Required**. Replacement value used to replace the [generic keyword](#iv--generics-keywords) in brackets |
|
135 |
|
136 |
|
137 | #### Options : `generate`
|
138 | | Option | Short | Type | Description | Default Value |
|
139 | |:-----------:|:-----:|:------:|:--------------------------------------------------------------------------------:|:-------------:|
|
140 | | `--subdomain` | `-s` | `string` | **Optional**. Path of subdomain. It should be relative to `componentWorkDir` or `rootWorkDir`. The subdomain will be placed between the `componentWorkDir` and `rootWorkDir` | none |
|
141 |
|
142 | ### C- List all templates
|
143 |
|
144 | ```cmd
|
145 | $ ccc list
|
146 | ```
|
147 | This command lists all available templates
|
148 |
|
149 | ### D- Display help interface
|
150 |
|
151 | ```cmd
|
152 | $ ccc --help
|
153 | ```
|
154 | This command displays a command line help interface
|
155 |
|
156 | ## IV- Generics keywords
|
157 | The genereric keywords are recognized by the CLI and replaced by the [reclacement value](#arguments--generate) provided.
|
158 |
|
159 | The value contained in generic keyword defines formatting result of `replacement value` argument :
|
160 |
|
161 |
|
162 | | Keyword | Formatting | Exemple |
|
163 | |:----------------:|:---------------------------------------------------:|:------------:|
|
164 | | `$none$` | Don't apply formatting | none |
|
165 | | `$camelCase$` | Capitalized word except first one. | exempleCase |
|
166 | | `$pascalCase$` | Capitalized word. | ExempleCase |
|
167 | | `$snakeCase$` | Lower case string with underscores between words. | exemple_case |
|
168 | | `$paramCase$` | Lower cased string with dashes between words. | exemple-case |
|
169 | | `$constantCase$` | Upper case string with an underscore between words. | EXEMPLE_CASE |
|
170 | | `$sentenceCase$` | Lower cased string with spaces between words. | exemple case |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 | ## V- Template structure
|
176 | ### A- Template directory structure
|
177 | #### `ccc-config/`
|
178 | ```
|
179 | my-project-directory/
|
180 | ├─ ccc-config/ ---> CLI config directory
|
181 | │ │
|
182 | │ ├─ my-extravagant-$none$/ ---> A custom template
|
183 | │ │ ├─ template-config.json ---> Component config file
|
184 | │ │ ├─ interfce-$none$.ts
|
185 | │ │ ├─ show-$none$-formated.html
|
186 | │ │ ├─ $none$-beauty.css
|
187 | │ │ ├─ test-my-$none$-please.test.ts
|
188 | │ │ └─ $none$.js
|
189 | │ │
|
190 | │ ├─ other$camelCase$Entity/ ---> Another template
|
191 | │ │ └─ ...
|
192 | │ │
|
193 | └─ ...
|
194 | ```
|
195 | The `ccc-config/`**CLI configuration directory is mandatory** and it must be created at the root of your project.
|
196 | In this directory you will stored all your templates like `my-extravagant-$none$` and `other$camelCase$Entity/`.
|
197 |
|
198 | - The keywords "`[none]`" and "`[camelCase]`" belongs to a family of [generics keywords](#iv--generics-keywords) .
|
199 | - On running `generate` command : Every `generic keywords` **will be replaced** by the [replacement value](#arguments--generate)
|
200 |
|
201 | ### B- Template config file properties
|
202 |
|
203 | #### `./template-config.json`
|
204 |
|
205 | | Field | Type | Description |
|
206 | |:---------------------------------------------------:|:--------------------:|:----------------------------------------------------------:|
|
207 | | `template` | `string` | **Required** & **Unique**. Template name. |
|
208 | | [`"componentWorkDirectory"`](#componentworkdirectory-string--object)| `string` \| `object` | **Required**. Used to set the component working directory. Should be **relative** to project directory |
|
209 | This configuration file is **mandatory**.
|
210 |
|
211 | #### `"componentWorkDirectory"`: string | object
|
212 | As **string** :
|
213 | | Field | Type | Description |
|
214 | |:--------------------------------------:|:--------:|:-----------------------------------------------------:|
|
215 | | `componentWorkDir` | `string` | **Required**. Component working directory. |
|
216 |
|
217 |
|
218 | As **object** :
|
219 |
|
220 | | Field | Type | Description |
|
221 | |:--------------------------------------:|:--------:|:-----------------------------------------------------:|
|
222 | | `componentWorkDir`.`rootWorkDir` | `string` | **Required**. Component working directory. Should be **relative** to project directory |
|
223 | | `componentWorkDir` .`extensionWorkDir` | `string` | **Optional**. Exention of component working directory. Should be relative to `rootWorkDir` |
|
224 |
|
225 |
|
226 | Use the "`componentWorkDir`" property as **object** when working with subdomains and want to create your components in different subdomains [like ewample 3](#example-3--use-componentworkdir-config-property-as-object) with "`--subdomain`" option.
|
227 |
|
228 | # Examples
|
229 | - In all the examples we will create a component from this '*repository*' template
|
230 | - All examples will use the same template
|
231 | - All the examples will use the **same template** and **same files contoent**
|
232 | - But all the examples will have **different** :
|
233 | - template **configuration file**
|
234 | - **project tree directory**
|
235 |
|
236 | Same 'repository' ***template** directory* `my-$paramCase$-repository/`
|
237 | ```
|
238 | ./ccc-config/
|
239 | ├─ my-$paramCase$-repository/
|
240 | │ ├─ template-config.json
|
241 | │ ├─ interface-$paramCase$-repository.ts
|
242 | │ ├─ implementation-$paramCase$-repository.ts
|
243 | │ ├─ $paramCase$-repository.test.ts
|
244 | └─ ...
|
245 | ```
|
246 | Same 'repository' ***template** file content* : `./interface-$paramCase$-repository.ts`
|
247 | ```typescript
|
248 | interface I$pascalCase$Repo {
|
249 | anyProperty : string
|
250 | hello : number
|
251 | getAll$pascalCase$ () : Object[]
|
252 | getOne$pascalCase$ () : Object
|
253 | }
|
254 | ```
|
255 | ### Example 1 : "Classic usage"
|
256 |
|
257 |
|
258 | \- example 1 **project** tree directory `/my-project-1`
|
259 | ```
|
260 | my-project-1/
|
261 | ├─ ccc-config/
|
262 | ├─ src/
|
263 | │ ├─ repos/
|
264 | ├─ node_modules/
|
265 | ├─ package.json
|
266 | └─ ...
|
267 | ```
|
268 |
|
269 | \- example 1 'repository' **template** config file `./template-config.json`
|
270 | - define at `/my-project-1/ccc-config/my-$paramCase$-repository/template-config.json`
|
271 | ```json
|
272 | {
|
273 | "template" : "repository",
|
274 | "componentWorkDir" :"src/repos"
|
275 | }
|
276 | ```
|
277 |
|
278 |
|
279 | \- example 1 **command** `generate`
|
280 | ```cmd
|
281 | ccc generate repository 'car'
|
282 | ```
|
283 | \- example 1 : **component** directory `my-car-repository/` generated at `/my-project-1/src/repos/my-car-repository`
|
284 | ```
|
285 | ./my-car-repository/
|
286 | ├─ interface-car-repository.ts/
|
287 | ├─ implementation-car-repository.ts/
|
288 | └─ car-repository.test.ts/
|
289 | ```
|
290 |
|
291 |
|
292 | \- example 1 **component** file content `./interface-car-repository.ts`
|
293 | ```typescript
|
294 | interface ICarRepo {
|
295 | anyProperty : string
|
296 | hello : number
|
297 | getAllCar () : Object[]
|
298 | getOneCar () : Object
|
299 | }
|
300 | ```
|
301 |
|
302 | ### Example 2 : "Set directory extension in generate command"
|
303 |
|
304 |
|
305 | \- example 2 **project** tree directory `/my-project-2`
|
306 | ```
|
307 | my-project-2/
|
308 | ├─ ccc-config/
|
309 | ├─ src/
|
310 | │ ├─ domain/
|
311 | │ ├─ infra/
|
312 | │ │ ├─ repos/
|
313 | │ │ ├─ mappers/
|
314 | │ │ ├─ .../
|
315 | ├─ node_modules/
|
316 | ├─ package.json
|
317 | └─ ...
|
318 | ```
|
319 |
|
320 | \- example 2 'repository' **template** config file `./template-config.json` define at `/my-project-2/ccc-config/my-$paramCase$-repository/template-config.json`
|
321 | ```json
|
322 | {
|
323 | "template" : "repository",
|
324 | "componentWorkDir" :"src"
|
325 | }
|
326 | ```
|
327 |
|
328 |
|
329 | \- example 2 **command** `generate`
|
330 | ```cmd
|
331 | ccc generate repository 'bus' -s ./infra/repos
|
332 | ```
|
333 | \- example 2 : **component** directory `my-bus-repository/`
|
334 | generated at `/my-project-2/src/infra/repos/my-bus-repository`
|
335 | ```
|
336 | ./my-bus-repository/
|
337 | ├─ interface-bus-repository.ts/
|
338 | ├─ implementation-bus-repository.ts/
|
339 | └─ bus-repository.test.ts/
|
340 | ```
|
341 |
|
342 |
|
343 | \- example 2 **component** file content `./interface-bus-repository.ts`
|
344 |
|
345 | ```typescript
|
346 | interface IBusRepo {
|
347 | anyProperty : string
|
348 | hello : number
|
349 | getAllBus () : Object[]
|
350 | getOneBus () : Object
|
351 | }
|
352 | ```
|
353 |
|
354 | ### Example 3 : "Use 'componentWorkDir' config property as object"
|
355 |
|
356 |
|
357 | \- example 3 **project** tree directory `/my-project-3`
|
358 | ```
|
359 | my-project-3/
|
360 | ├─ ccc-config/
|
361 | ├─ src/
|
362 | │ ├─ boundedCtx1/
|
363 | │ ├─ boundedCtx2/
|
364 | │ ├─ boundedCtx3/
|
365 | │ │ ├─ domain/
|
366 | │ │ ├─ infra/
|
367 | │ │ │ ├─ repos/
|
368 | │ │ │ ├─ mappers/
|
369 | │ │ │ ├─ .../
|
370 | ├─ node_modules/
|
371 | ├─ package.json
|
372 | └─ ...
|
373 | ```
|
374 |
|
375 | \- example 3 'repository' **template** config file `./template-config.json`
|
376 | define at `/my-project-3/ccc-config/my-$paramCase$-repository/template-config.json`
|
377 | ```json
|
378 | {
|
379 | "template" : "repository",
|
380 | "componentWorkDir" :{
|
381 | "rootWorkDir" : "src",
|
382 | "extensionWorkDir" : "infra/repos",
|
383 | }
|
384 | }
|
385 | ```
|
386 | \- example 3 **command** `generate`
|
387 | ```cmd
|
388 | ccc generate repository 'taxi' -s ./boundedCtx3
|
389 | ```
|
390 | \- example 3 : **component** directory `my-taxi-repository/`
|
391 | generated at `/my-project-3/src/`**`boundedCtx3`**`/infra/repos/my-taxi-repository`
|
392 | ```
|
393 | ./my-taxi-repository/
|
394 | ├─ interface-taxi-repository.ts/
|
395 | ├─ implementation-taxi-repository.ts/
|
396 | └─ taxi-repository.test.ts/
|
397 | ```
|
398 | As we can see, the "`--subdomain`" command option allows to place a *subdomain* **between** the `rootWorkDir`and "`extensionWorkDir`" paths
|
399 |
|
400 | \- example 3 **component** file content `./interface-taxi-repository.ts`
|
401 |
|
402 | ```typescript
|
403 | interface ITaxiRepo {
|
404 | anyProperty : string
|
405 | hello : number
|
406 | getAllTaxi () : Object[]
|
407 | getOneTaxi () : Object
|
408 | }
|
409 | ```
|
410 |
|
411 |
|
412 | # License & Author
|
413 |
|
414 | ##### Lience : [MIT](https://choosealicense.com/licenses/mit/)
|
415 |
|
416 | ##### Author : [@enzo-cora](https://www.github.com/enzo-cora) |
\ | No newline at end of file |