tshex-cli 1.0.16 → 1.0.18

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.
Files changed (40) hide show
  1. package/README.es.md +1449 -0
  2. package/README.md +1449 -0
  3. package/build/main.js +11 -38
  4. package/package.json +8 -10
  5. package/source/main.ts +11 -44
  6. package/templates/ctx/example-ports.ts +5 -0
  7. package/templates/lib/shared/application/data-sources.ts +102 -0
  8. package/templates/lib/shared/application/http.ts +28 -40
  9. package/templates/lib/shared/application/loggers.ts +6 -30
  10. package/templates/lib/shared/application/validations.ts +10 -0
  11. package/readme.md +0 -229
  12. package/templates/ctx/index.ts +0 -0
  13. package/templates/lib/shared/application/databases.ts +0 -81
  14. package/templates/react-project/core/context/adapters/api/.gitkeep +0 -0
  15. package/templates/react-project/core/context/adapters/hooks/.gitkeep +0 -0
  16. package/templates/react-project/core/context/adapters/schemas/.gitkeep +0 -0
  17. package/templates/react-project/core/context/application/.gitkeep +0 -0
  18. package/templates/react-project/core/context/domain/.gitkeep +0 -0
  19. package/templates/react-project/core/context/languages/.gitkeep +0 -0
  20. package/templates/react-project/core/shared/adapters/i18n/.gitkeep +0 -0
  21. package/templates/react-project/dom-client/context/Example.tsx +0 -11
  22. package/templates/react-project/dom-client/context/assets/.gitkeep +0 -0
  23. package/templates/react-project/dom-client/context/styles/.gitkeep +0 -0
  24. package/templates/react-project/dom-server/context/Example.tsx +0 -11
  25. package/templates/react-project/dom-server/context/assets/.gitkeep +0 -0
  26. package/templates/react-project/dom-server/context/styles/.gitkeep +0 -0
  27. package/templates/react-project/index.d.ts +0 -1
  28. package/templates/react-project/native/context/Example.tsx +0 -11
  29. package/templates/react-project/native/context/assets/.gitkeep +0 -0
  30. package/templates/react-project/native/context/styles/.gitkeep +0 -0
  31. package/templates/react-project/tests/core/.gitkeep +0 -0
  32. package/templates/react-project/tests/dom-client/.gitkeep +0 -0
  33. package/templates/react-project/tests/dom-server/.gitkeep +0 -0
  34. package/templates/react-project/tests/native/.gitkeep +0 -0
  35. /package/templates/{react-context → ctx-react}/adapters/api/.gitkeep +0 -0
  36. /package/templates/{react-context → ctx-react}/adapters/hooks/.gitkeep +0 -0
  37. /package/templates/{react-context → ctx-react}/adapters/schemas/.gitkeep +0 -0
  38. /package/templates/{react-context → ctx-react}/application/.gitkeep +0 -0
  39. /package/templates/{react-context → ctx-react}/domain/.gitkeep +0 -0
  40. /package/templates/{react-context → ctx-react}/languages/.gitkeep +0 -0
package/build/main.js CHANGED
@@ -31,35 +31,9 @@ function executeCreateContext(templatesDir, contextDir) {
31
31
  console.error(err);
32
32
  }
33
33
  }
34
- function copyDirectoryContents(sourceDir, destinationDir) {
35
- const entries = fs.readdirSync(sourceDir, { withFileTypes: true });
36
- for (const entry of entries) {
37
- const sourcePath = path.join(sourceDir, entry.name);
38
- const destinationPath = path.join(destinationDir, entry.name);
39
- if (fs.existsSync(destinationPath) === false) {
40
- fs.cpSync(sourcePath, destinationPath, {
41
- recursive: true,
42
- filter: (src) => src.endsWith('.gitkeep') === false
43
- });
44
- }
45
- }
46
- }
47
- function executeCreateReactProject(templatesDir, projectDir) {
48
- try {
49
- fs.cpSync(path.join(templatesDir, 'react-project'), projectDir, {
50
- recursive: true,
51
- filter: (src) => src.endsWith('.gitkeep') === false
52
- });
53
- copyDirectoryContents(path.join(templatesDir, 'lib', 'shared'), path.join(projectDir, 'core', 'shared'));
54
- console.log('React project created successfully');
55
- }
56
- catch (err) {
57
- console.error(err);
58
- }
59
- }
60
34
  function executeCreateReactContext(templatesDir, contextDir) {
61
35
  try {
62
- fs.cpSync(path.join(templatesDir, 'react-context'), contextDir, {
36
+ fs.cpSync(path.join(templatesDir, 'ctx-react'), contextDir, {
63
37
  recursive: true,
64
38
  filter: (src) => src.endsWith('.gitkeep') === false
65
39
  });
@@ -83,17 +57,17 @@ function main(program) {
83
57
  targetDir = path.join(targetDir, options.lib);
84
58
  executeCreateLib(templatesDir, targetDir);
85
59
  }
60
+ if (options.react === true && options.ctx === undefined) {
61
+ program.error('Option --react requires --ctx <name>');
62
+ }
86
63
  if (options.ctx !== undefined) {
87
64
  targetDir = path.join(targetDir, options.ctx);
88
- executeCreateContext(templatesDir, targetDir);
89
- }
90
- if (options.reactProject !== undefined) {
91
- targetDir = path.join(targetDir, options.reactProject);
92
- executeCreateReactProject(templatesDir, targetDir);
93
- }
94
- if (options.reactContext !== undefined) {
95
- targetDir = path.join(targetDir, options.reactContext);
96
- executeCreateReactContext(templatesDir, targetDir);
65
+ if (options.react === true) {
66
+ executeCreateReactContext(templatesDir, targetDir);
67
+ }
68
+ else {
69
+ executeCreateContext(templatesDir, targetDir);
70
+ }
97
71
  }
98
72
  }
99
73
  const packageJson = readPackageJson();
@@ -102,8 +76,7 @@ program
102
76
  .version(packageJson.version)
103
77
  .option('--lib <name>', "creates a new library with it's shared directory")
104
78
  .option('--ctx <name>', 'creates a new context')
79
+ .option('-R, --react', 'creates a React context with --ctx')
105
80
  .option('--dir <path>', 'sets the directory to create the new item')
106
- .option('--react-project <name>', 'creates a new React project')
107
- .option('--react-context <name>', 'creates a new React context')
108
81
  .parse(process.argv);
109
82
  main(program);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tshex-cli",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "author": "https://github.com/virtualitems/",
5
5
  "description": "Typescript Hexagonal Architecture CLI",
6
6
  "type": "module",
@@ -26,25 +26,23 @@
26
26
  "bugs": {
27
27
  "url": "https://github.com/virtualitems/tshex-cli/issues"
28
28
  },
29
+ "types": "./source/index.d.ts",
29
30
  "files": [
30
31
  "./build",
31
32
  "./source",
32
33
  "./templates"
33
34
  ],
34
- "types": "./source/index.d.ts",
35
- "devDependencies": {
36
- "@types/node": "^22.5.4",
37
- "typescript": "^5.4.5"
35
+ "bin": {
36
+ "tshex": "./build/main.js"
38
37
  },
39
38
  "dependencies": {
40
39
  "commander": "^12.1.0"
41
40
  },
42
- "bin": {
43
- "tshex": "./build/main.js"
41
+ "devDependencies": {
42
+ "@types/node": "^22.5.4",
43
+ "typescript": "^5.4.5"
44
44
  },
45
45
  "scripts": {
46
- "examples": "tsc -p examples",
47
- "build": "tsc",
48
- "dev": "tsc -w"
46
+ "build": "tsc"
49
47
  }
50
48
  }
package/source/main.ts CHANGED
@@ -41,40 +41,9 @@ function executeCreateContext(templatesDir: string, contextDir: string) {
41
41
  }
42
42
  }
43
43
 
44
- function copyDirectoryContents(sourceDir: string, destinationDir: string) {
45
- const entries = fs.readdirSync(sourceDir, { withFileTypes: true })
46
-
47
- for (const entry of entries) {
48
- const sourcePath = path.join(sourceDir, entry.name)
49
- const destinationPath = path.join(destinationDir, entry.name)
50
-
51
- if (fs.existsSync(destinationPath) === false) {
52
- fs.cpSync(sourcePath, destinationPath, {
53
- recursive: true,
54
- filter: (src) => src.endsWith('.gitkeep') === false
55
- })
56
- }
57
- }
58
- }
59
-
60
- function executeCreateReactProject(templatesDir: string, projectDir: string) {
61
- try {
62
- fs.cpSync(path.join(templatesDir, 'react-project'), projectDir, {
63
- recursive: true,
64
- filter: (src) => src.endsWith('.gitkeep') === false
65
- })
66
-
67
- copyDirectoryContents(path.join(templatesDir, 'lib', 'shared'), path.join(projectDir, 'core', 'shared'))
68
-
69
- console.log('React project created successfully')
70
- } catch (err) {
71
- console.error(err)
72
- }
73
- }
74
-
75
44
  function executeCreateReactContext(templatesDir: string, contextDir: string) {
76
45
  try {
77
- fs.cpSync(path.join(templatesDir, 'react-context'), contextDir, {
46
+ fs.cpSync(path.join(templatesDir, 'ctx-react'), contextDir, {
78
47
  recursive: true,
79
48
  filter: (src) => src.endsWith('.gitkeep') === false
80
49
  })
@@ -104,19 +73,18 @@ function main(program: typeof import('commander').program) {
104
73
  executeCreateLib(templatesDir, targetDir)
105
74
  }
106
75
 
107
- if (options.ctx !== undefined) {
108
- targetDir = path.join(targetDir, options.ctx)
109
- executeCreateContext(templatesDir, targetDir)
76
+ if (options.react === true && options.ctx === undefined) {
77
+ program.error('Option --react requires --ctx <name>')
110
78
  }
111
79
 
112
- if (options.reactProject !== undefined) {
113
- targetDir = path.join(targetDir, options.reactProject)
114
- executeCreateReactProject(templatesDir, targetDir)
115
- }
80
+ if (options.ctx !== undefined) {
81
+ targetDir = path.join(targetDir, options.ctx)
116
82
 
117
- if (options.reactContext !== undefined) {
118
- targetDir = path.join(targetDir, options.reactContext)
119
- executeCreateReactContext(templatesDir, targetDir)
83
+ if (options.react === true) {
84
+ executeCreateReactContext(templatesDir, targetDir)
85
+ } else {
86
+ executeCreateContext(templatesDir, targetDir)
87
+ }
120
88
  }
121
89
  }
122
90
 
@@ -127,9 +95,8 @@ program
127
95
  .version(packageJson.version)
128
96
  .option('--lib <name>', "creates a new library with it's shared directory")
129
97
  .option('--ctx <name>', 'creates a new context')
98
+ .option('-R, --react', 'creates a React context with --ctx')
130
99
  .option('--dir <path>', 'sets the directory to create the new item')
131
- .option('--react-project <name>', 'creates a new React project')
132
- .option('--react-context <name>', 'creates a new React context')
133
100
  .parse(process.argv)
134
101
 
135
102
  main(program)
@@ -0,0 +1,5 @@
1
+ // Ports are exports from the context root level
2
+
3
+ export function example(): void {
4
+ // ...
5
+ }
@@ -0,0 +1,102 @@
1
+ type Generic<T = unknown> = Record<string, T>
2
+
3
+ /**
4
+ * @description
5
+ */
6
+ export interface Filterable<S = Generic> {
7
+ filter(selector: S): Promise<Array<S>>
8
+ }
9
+
10
+ /**
11
+ * @description
12
+ */
13
+ export interface Sortable<S = Generic> {
14
+ sort(selector: S): Promise<Array<S>>
15
+ }
16
+
17
+ /**
18
+ * @description
19
+ */
20
+ export interface Creatable<D = Generic> {
21
+ create(data: D): Promise<unknown>
22
+ }
23
+
24
+ /**
25
+ * @description
26
+ */
27
+ export interface Updatable<S = Generic, D = Generic> {
28
+ update(selector: S, data: D): Promise<unknown>
29
+ }
30
+
31
+ /**
32
+ * @description
33
+ */
34
+ export interface Deletable<S = Generic> {
35
+ delete(selector: S): Promise<unknown>
36
+ }
37
+
38
+ /**
39
+ * @description
40
+ */
41
+ export interface Aggregatable<S = Generic> {
42
+ aggregate(selector: S): Promise<S>
43
+ }
44
+
45
+ /**
46
+ * @description
47
+ */
48
+ export interface Relatable {
49
+ selectRelated(...args: unknown[]): unknown
50
+
51
+ prefetchRelated(...args: unknown[]): unknown
52
+ }
53
+
54
+ /**
55
+ * @description
56
+ */
57
+ export abstract class DataManager<T = Generic> {
58
+ [property: string]: unknown
59
+
60
+ public abstract all(): Promise<Array<T>>
61
+
62
+ public abstract none(): Array<T>
63
+ } //:: class
64
+
65
+ /**
66
+ * @description
67
+ */
68
+ export abstract class DatasetManager<T = Generic> extends DataManager<T> {
69
+ [property: string]: unknown
70
+
71
+ public abstract union(other: Array<T>): Promise<Array<T>>
72
+
73
+ public abstract intersection(other: Array<T>): Promise<Array<T>>
74
+
75
+ public abstract difference(other: Array<T>): Promise<Array<T>>
76
+
77
+ public abstract symmetricDifference(other: Array<T>): Promise<Array<T>>
78
+
79
+ public abstract complement(other: Array<T>): Promise<Array<T>>
80
+ } //:: class
81
+
82
+ /**
83
+ * @description
84
+ */
85
+ export abstract class DriverManager<M extends DataManager = DataManager> {
86
+ [property: string]: unknown
87
+
88
+ public abstract connect(...args: unknown[]): Promise<M>
89
+
90
+ public abstract disconnect(): Promise<unknown>
91
+ } //:: class
92
+
93
+ /**
94
+ * @description Represents a data source.
95
+ */
96
+ export abstract class Repository<M extends DriverManager = DriverManager> {
97
+ [property: string]: unknown
98
+
99
+ public constructor(public readonly manager: M) {}
100
+
101
+ protected abstract transform<T = Generic>(data: Generic): T
102
+ } //:: class
@@ -1,48 +1,36 @@
1
- // Libraries
2
-
3
- // Same Layer
4
-
5
- // Lower Layers
6
-
7
- // Types
1
+ /**
2
+ * @description
3
+ */
4
+ export interface HttpRequest {}
8
5
 
9
- // Constants
6
+ /**
7
+ * @description
8
+ */
9
+ export interface HttpResponse {}
10
10
 
11
11
  /**
12
12
  * @description
13
13
  */
14
- export class HttpResponseBody {
14
+ export interface HttpResponseBody {
15
15
  [property: string]: unknown
16
+ readonly data: Record<string, unknown> | null
17
+ readonly errors: string[] | null
18
+ readonly links: Record<string, URL> | null
19
+ }
16
20
 
17
- // public ATTRIBUTES
18
-
19
- // protected ATTRIBUTES
20
-
21
- // private ATTRIBUTES
22
-
23
- // public static ATTRIBUTES
24
-
25
- // protected static ATTRIBUTES
26
-
27
- // private static ATTRIBUTES
28
-
29
- // Constructor, Getters, Setters
30
-
31
- public constructor(
32
- public readonly data: Record<string, unknown> | null = null,
33
- public readonly errors: string[] | null = null,
34
- public readonly links: Record<string, URL> | null = null
35
- ) {}
36
-
37
- // public METHODS
38
-
39
- // protected METHODS
40
-
41
- // private METHODS
42
-
43
- // public static METHODS
44
-
45
- // protected static METHODS
21
+ /**
22
+ * @description
23
+ */
24
+ export interface HttpRequestHandler {
25
+ handle(request: HttpRequest): HttpResponse | Promise<HttpResponse>
26
+ }
46
27
 
47
- // private static METHODS
48
- } //:: class
28
+ /**
29
+ * @description
30
+ */
31
+ export interface HttpMiddleware {
32
+ process(
33
+ request: HttpRequest,
34
+ handler: HttpRequestHandler
35
+ ): HttpResponse | Promise<HttpResponse>
36
+ }
@@ -1,12 +1,12 @@
1
- // Libraries
1
+ export const DEBUG = 10
2
2
 
3
- // Same Layer
3
+ export const INFO = 20
4
4
 
5
- // Lower Layers
5
+ export const WARNING = 30
6
6
 
7
- // Types
7
+ export const ERROR = 40
8
8
 
9
- // Constants
9
+ export const CRITICAL = 50
10
10
 
11
11
  /**
12
12
  * @description
@@ -14,22 +14,6 @@
14
14
  export abstract class Logger {
15
15
  [property: string]: unknown
16
16
 
17
- // public ATTRIBUTES
18
-
19
- // protected ATTRIBUTES
20
-
21
- // private ATTRIBUTES
22
-
23
- // public static ATTRIBUTES
24
-
25
- // protected static ATTRIBUTES
26
-
27
- // private static ATTRIBUTES
28
-
29
- // Constructor, Getters, Setters
30
-
31
- // public METHODS
32
-
33
17
  public abstract debug(data: unknown): void
34
18
 
35
19
  public abstract info(data: unknown): void
@@ -38,13 +22,5 @@ export abstract class Logger {
38
22
 
39
23
  public abstract error(data: unknown): void
40
24
 
41
- // protected METHODS
42
-
43
- // private METHODS
44
-
45
- // public static METHODS
46
-
47
- // protected static METHODS
48
-
49
- // private static METHODS
25
+ public abstract critical(data: unknown): void
50
26
  } //:: class
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @description
3
+ */
4
+ export interface Validatable {
5
+ [property: string]: unknown
6
+
7
+ isValid(): boolean
8
+
9
+ validate(): unknown
10
+ }
package/readme.md DELETED
@@ -1,229 +0,0 @@
1
- # Hexagonal Architecture CLI
2
-
3
- This CLI will help you to generate a hexagonal architecture structure.
4
-
5
- # Why?
6
-
7
- Hexagonal architecture is a software design pattern that separates the internal domain of the application from the external dependencies. This separation is achieved by dividing the application into layers. Each layer has a specific responsibility and interacts with the other layers in a specific way.
8
-
9
- The goal is to separate the domain code from installed dependencies. A Hexagonal Architecture _framework_ would work against that goal, since it couples the domain code to the framework itself. That is why this CLI exists: it scaffolds the structure for you, using your own codebase instead of a framework.
10
-
11
- # Note
12
-
13
- This tool and its templates are in constant development, so be aware that some changes may occur and be careful when updating the tool.
14
-
15
- If you have any suggestions or improvements, please let me know.
16
-
17
- https://github.com/virtualitems/tshex-cli/issues
18
-
19
- # Getting started
20
-
21
- `tshex` scaffolds folders and files for a hexagonal architecture project. It does not write business logic for you; it only generates the structure, so you can fill it in with your own code.
22
-
23
- There are four things you can generate:
24
-
25
- - A **library** (`--lib`): the shared foundation of a project. It contains the domain and application contracts (entities, value objects, services, etc.) that the rest of the code depends on.
26
- - A **context** (`--ctx`): a specific business area (e.g. `users`, `billing`, `orders`). It contains the `domain/`, `application/`, and `adapters/` folders where you implement that area's logic.
27
- - A **React project** (`--react-project`): a full React-oriented hexagonal structure with `core/`, `dom-client/`, `dom-server/`, and `native/` folders.
28
- - A **React context** (`--react-context`): a React-ready context scaffold.
29
-
30
- A typical project has one library and one or more contexts inside it.
31
-
32
- ## Install
33
-
34
- Install the CLI globally:
35
-
36
- ```bash
37
- npm install -g tshex-cli
38
- ```
39
-
40
- Check the installation:
41
-
42
- ```bash
43
- tshex --version
44
- ```
45
-
46
- Show the command options:
47
-
48
- ```bash
49
- tshex --help
50
- ```
51
-
52
- ## Usage
53
-
54
- ```bash
55
- tshex [--lib <name>] [--ctx <name>] [--react-project <name>] [--react-context <name>] [--dir <path>]
56
- ```
57
-
58
- | Option | Purpose |
59
- | -------------- | ------------------------------------------------------------------- |
60
- | `--lib <name>` | Generate a library called `<name>`, based on `templates/lib`. |
61
- | `--ctx <name>` | Generate a context called `<name>`, based on `templates/ctx`. |
62
- | `--react-project <name>` | Generate a React project called `<name>`, based on `templates/react-project` and `templates/lib/shared`. |
63
- | `--react-context <name>` | Generate a React context called `<name>`, based on `templates/react-context`. |
64
- | `--dir <path>` | Parent directory where the library/context will be created. Defaults to the current directory. |
65
- | `--help` | Show the command options. |
66
- | `--version` | Show the installed version. |
67
-
68
- `--lib`, `--ctx`, `--react-project`, and `--react-context` can be used together in a single command. Running `tshex` without any options just prints the help text — it does not generate anything.
69
-
70
- ## Create a library
71
-
72
- Use this when you are starting a new project and need the shared contracts that the rest of your code will build on:
73
-
74
- ```bash
75
- tshex --lib core
76
- ```
77
-
78
- This generates a `core/` folder in the current directory:
79
-
80
- ```text
81
- core/
82
- ├── index.d.ts
83
- ├── main.ts
84
- └── shared/
85
- ├── application/
86
- │ ├── databases.ts
87
- │ ├── events.ts
88
- │ ├── http.ts
89
- │ ├── loggers.ts
90
- │ └── services.ts
91
- └── domain/
92
- ├── aggregates.ts
93
- ├── entities.ts
94
- ├── errors.ts
95
- └── value-objects.ts
96
- ```
97
-
98
- What each file is for:
99
-
100
- | File | Purpose |
101
- | ------------------ | --------------------------------------------- |
102
- | `index.d.ts` | Declare library types. |
103
- | `main.ts` | Export the library API. |
104
- | `entities.ts` | Define entity contracts. |
105
- | `value-objects.ts` | Define value objects and validation. |
106
- | `aggregates.ts` | Define aggregate contracts. |
107
- | `errors.ts` | Define domain errors. |
108
- | `services.ts` | Define application service contracts. |
109
- | `databases.ts` | Define data manager and repository contracts. |
110
- | `events.ts` | Define event contracts. |
111
- | `http.ts` | Define HTTP response contracts. |
112
- | `loggers.ts` | Define logger contracts. |
113
-
114
- `main.ts` is generated with a placeholder `throw new Error('Not implemented yet')`, so the library fails loudly if you try to use it before filling it in. To start using it, open `main.ts`, remove that line, and export your own code, built on top of the shared contracts. For example:
115
-
116
- ```ts
117
- export { Entity } from './shared/domain/entities.js'
118
- export { ValueObject, Email } from './shared/domain/value-objects.js'
119
-
120
- class User extends Entity {
121
- constructor(public readonly email: Email) {
122
- super()
123
- }
124
- }
125
- ```
126
-
127
- ## Create a context
128
-
129
- Use this to scaffold a specific business area, such as `users`, inside an existing library (or on its own):
130
-
131
- ```bash
132
- tshex --ctx users
133
- ```
134
-
135
- This generates a `users/` folder in the current directory:
136
-
137
- ```text
138
- users/
139
- ├── adapters/
140
- ├── application/
141
- ├── domain/
142
- └── index.ts
143
- ```
144
-
145
- What each part is for:
146
-
147
- | Path | Purpose |
148
- | -------------- | ---------------------------------------------------------------- |
149
- | `domain/` | Entities, value objects, aggregates, and domain errors. |
150
- | `application/` | Use cases, services, DTOs, and contracts. |
151
- | `adapters/` | Database, HTTP, event, file, and service implementations. |
152
- | `index.ts` | Export or compose the context's public API. |
153
-
154
- ## Choose the destination folder
155
-
156
- By default, `tshex` creates files in your current directory. Use `--dir` to choose a different parent directory instead.
157
-
158
- Create a library inside `./src`:
159
-
160
- ```bash
161
- tshex --lib core --dir ./src
162
- ```
163
-
164
- This generates the library at:
165
-
166
- ```text
167
- ./src/core
168
- ```
169
-
170
- Create a context inside that library:
171
-
172
- ```bash
173
- tshex --ctx users --dir ./src/core
174
- ```
175
-
176
- This generates the context at:
177
-
178
- ```text
179
- ./src/core/users
180
- ```
181
-
182
- You can also use an absolute path:
183
-
184
- ```bash
185
- tshex --ctx users --dir /workspace/project/src
186
- ```
187
-
188
- ## Create a library and a context together
189
-
190
- You can generate both in a single command. `tshex` creates the library first, then creates the context inside it:
191
-
192
- ```bash
193
- tshex --dir ./src --lib core --ctx users
194
- ```
195
-
196
- Result:
197
-
198
- ```text
199
- src/
200
- └── core/
201
- ├── index.d.ts
202
- ├── main.ts
203
- ├── shared/
204
- └── users/
205
- ├── adapters/
206
- ├── application/
207
- ├── domain/
208
- └── index.ts
209
- ```
210
-
211
- ## Create a React project
212
-
213
- Use this when you want the React-specific project scaffold with the shared `core/shared` contracts copied from the library template:
214
-
215
- ```bash
216
- tshex --react-project app
217
- ```
218
-
219
- This generates a `app/` folder in the current directory.
220
-
221
- ## Create a React context
222
-
223
- Use this when you want only the React context scaffold:
224
-
225
- ```bash
226
- tshex --react-context users
227
- ```
228
-
229
- This generates a `users/` folder in the current directory.
File without changes