tshex-cli 1.0.16 → 1.0.17
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/build/main.js +11 -38
- package/package.json +1 -1
- package/readme.md +2 -14
- package/source/main.ts +11 -44
- package/templates/ctx/example-ports.ts +5 -0
- package/templates/lib/shared/application/databases.ts +70 -49
- package/templates/lib/shared/application/loggers.ts +6 -30
- package/templates/lib/shared/application/validations.ts +10 -0
- package/templates/ctx/index.ts +0 -0
- package/templates/react-project/core/context/adapters/api/.gitkeep +0 -0
- package/templates/react-project/core/context/adapters/hooks/.gitkeep +0 -0
- package/templates/react-project/core/context/adapters/schemas/.gitkeep +0 -0
- package/templates/react-project/core/context/application/.gitkeep +0 -0
- package/templates/react-project/core/context/domain/.gitkeep +0 -0
- package/templates/react-project/core/context/languages/.gitkeep +0 -0
- package/templates/react-project/core/shared/adapters/i18n/.gitkeep +0 -0
- package/templates/react-project/dom-client/context/Example.tsx +0 -11
- package/templates/react-project/dom-client/context/assets/.gitkeep +0 -0
- package/templates/react-project/dom-client/context/styles/.gitkeep +0 -0
- package/templates/react-project/dom-server/context/Example.tsx +0 -11
- package/templates/react-project/dom-server/context/assets/.gitkeep +0 -0
- package/templates/react-project/dom-server/context/styles/.gitkeep +0 -0
- package/templates/react-project/index.d.ts +0 -1
- package/templates/react-project/native/context/Example.tsx +0 -11
- package/templates/react-project/native/context/assets/.gitkeep +0 -0
- package/templates/react-project/native/context/styles/.gitkeep +0 -0
- package/templates/react-project/tests/core/.gitkeep +0 -0
- package/templates/react-project/tests/dom-client/.gitkeep +0 -0
- package/templates/react-project/tests/dom-server/.gitkeep +0 -0
- package/templates/react-project/tests/native/.gitkeep +0 -0
- /package/templates/{react-context → ctx-react}/adapters/api/.gitkeep +0 -0
- /package/templates/{react-context → ctx-react}/adapters/hooks/.gitkeep +0 -0
- /package/templates/{react-context → ctx-react}/adapters/schemas/.gitkeep +0 -0
- /package/templates/{react-context → ctx-react}/application/.gitkeep +0 -0
- /package/templates/{react-context → ctx-react}/domain/.gitkeep +0 -0
- /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
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
package/readme.md
CHANGED
|
@@ -24,7 +24,6 @@ There are four things you can generate:
|
|
|
24
24
|
|
|
25
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
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
27
|
- A **React context** (`--react-context`): a React-ready context scaffold.
|
|
29
28
|
|
|
30
29
|
A typical project has one library and one or more contexts inside it.
|
|
@@ -52,20 +51,19 @@ tshex --help
|
|
|
52
51
|
## Usage
|
|
53
52
|
|
|
54
53
|
```bash
|
|
55
|
-
tshex [--lib <name>] [--ctx <name>] [--react-
|
|
54
|
+
tshex [--lib <name>] [--ctx <name>] [--react-context <name>] [--dir <path>]
|
|
56
55
|
```
|
|
57
56
|
|
|
58
57
|
| Option | Purpose |
|
|
59
58
|
| -------------- | ------------------------------------------------------------------- |
|
|
60
59
|
| `--lib <name>` | Generate a library called `<name>`, based on `templates/lib`. |
|
|
61
60
|
| `--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
61
|
| `--react-context <name>` | Generate a React context called `<name>`, based on `templates/react-context`. |
|
|
64
62
|
| `--dir <path>` | Parent directory where the library/context will be created. Defaults to the current directory. |
|
|
65
63
|
| `--help` | Show the command options. |
|
|
66
64
|
| `--version` | Show the installed version. |
|
|
67
65
|
|
|
68
|
-
`--lib`, `--ctx`,
|
|
66
|
+
`--lib`, `--ctx`, 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
67
|
|
|
70
68
|
## Create a library
|
|
71
69
|
|
|
@@ -208,16 +206,6 @@ src/
|
|
|
208
206
|
└── index.ts
|
|
209
207
|
```
|
|
210
208
|
|
|
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
209
|
## Create a React context
|
|
222
210
|
|
|
223
211
|
Use this when you want only the React context scaffold:
|
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
|
|
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
|
|
108
|
-
|
|
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.
|
|
113
|
-
targetDir = path.join(targetDir, options.
|
|
114
|
-
executeCreateReactProject(templatesDir, targetDir)
|
|
115
|
-
}
|
|
80
|
+
if (options.ctx !== undefined) {
|
|
81
|
+
targetDir = path.join(targetDir, options.ctx)
|
|
116
82
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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)
|
|
@@ -1,81 +1,102 @@
|
|
|
1
|
-
|
|
1
|
+
type Generic<T = unknown> = Record<string, T>
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* @description
|
|
5
|
+
*/
|
|
6
|
+
export interface Filterable<S = Generic> {
|
|
7
|
+
filter(selector: S): Promise<Array<S>>
|
|
8
|
+
}
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
/**
|
|
11
|
+
* @description
|
|
12
|
+
*/
|
|
13
|
+
export interface Sortable<S = Generic> {
|
|
14
|
+
sort(selector: S): Promise<Array<S>>
|
|
15
|
+
}
|
|
6
16
|
|
|
7
|
-
|
|
17
|
+
/**
|
|
18
|
+
* @description
|
|
19
|
+
*/
|
|
20
|
+
export interface Creatable<D = Generic> {
|
|
21
|
+
create(data: D): Promise<unknown>
|
|
22
|
+
}
|
|
8
23
|
|
|
9
|
-
|
|
24
|
+
/**
|
|
25
|
+
* @description
|
|
26
|
+
*/
|
|
27
|
+
export interface Updatable<S = Generic, D = Generic> {
|
|
28
|
+
update(selector: S, data: D): Promise<unknown>
|
|
29
|
+
}
|
|
10
30
|
|
|
11
31
|
/**
|
|
12
32
|
* @description
|
|
13
33
|
*/
|
|
14
|
-
export
|
|
15
|
-
|
|
34
|
+
export interface Deletable<S = Generic> {
|
|
35
|
+
delete(selector: S): Promise<unknown>
|
|
36
|
+
}
|
|
16
37
|
|
|
17
|
-
|
|
38
|
+
/**
|
|
39
|
+
* @description
|
|
40
|
+
*/
|
|
41
|
+
export interface Aggregatable<S = Generic> {
|
|
42
|
+
aggregate(selector: S): Promise<S>
|
|
43
|
+
}
|
|
18
44
|
|
|
19
|
-
|
|
45
|
+
/**
|
|
46
|
+
* @description
|
|
47
|
+
*/
|
|
48
|
+
export interface Relatable {
|
|
49
|
+
selectRelated(...args: unknown[]): unknown
|
|
20
50
|
|
|
21
|
-
|
|
51
|
+
prefetchRelated(...args: unknown[]): unknown
|
|
52
|
+
}
|
|
22
53
|
|
|
23
|
-
|
|
54
|
+
/**
|
|
55
|
+
* @description
|
|
56
|
+
*/
|
|
57
|
+
export abstract class DataManager<T = Generic> {
|
|
58
|
+
[property: string]: unknown
|
|
24
59
|
|
|
25
|
-
|
|
60
|
+
public abstract all(): Promise<Array<T>>
|
|
26
61
|
|
|
27
|
-
|
|
62
|
+
public abstract none(): Array<T>
|
|
63
|
+
} //:: class
|
|
28
64
|
|
|
29
|
-
|
|
65
|
+
/**
|
|
66
|
+
* @description
|
|
67
|
+
*/
|
|
68
|
+
export abstract class DatasetManager<T = Generic> extends DataManager<T> {
|
|
69
|
+
[property: string]: unknown
|
|
30
70
|
|
|
31
|
-
|
|
71
|
+
public abstract union(other: Array<T>): Promise<Array<T>>
|
|
32
72
|
|
|
33
|
-
public abstract
|
|
73
|
+
public abstract intersection(other: Array<T>): Promise<Array<T>>
|
|
34
74
|
|
|
35
|
-
public abstract
|
|
75
|
+
public abstract difference(other: Array<T>): Promise<Array<T>>
|
|
36
76
|
|
|
37
|
-
|
|
77
|
+
public abstract symmetric_difference(other: Array<T>): Promise<Array<T>>
|
|
38
78
|
|
|
39
|
-
|
|
79
|
+
public abstract complement(other: Array<T>): Promise<Array<T>>
|
|
80
|
+
} //:: class
|
|
40
81
|
|
|
41
|
-
|
|
82
|
+
/**
|
|
83
|
+
* @description
|
|
84
|
+
*/
|
|
85
|
+
export abstract class DriverManager<M extends DataManager = DataManager> {
|
|
86
|
+
[property: string]: unknown
|
|
42
87
|
|
|
43
|
-
|
|
88
|
+
public abstract connect(...args: unknown[]): Promise<M>
|
|
44
89
|
|
|
45
|
-
|
|
90
|
+
public abstract disconnect(): Promise<unknown>
|
|
46
91
|
} //:: class
|
|
47
92
|
|
|
48
93
|
/**
|
|
49
94
|
* @description Represents a data source.
|
|
50
95
|
*/
|
|
51
|
-
export abstract class Repository<
|
|
96
|
+
export abstract class Repository<M extends DriverManager = DriverManager> {
|
|
52
97
|
[property: string]: unknown
|
|
53
98
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// Protected Attributes
|
|
57
|
-
|
|
58
|
-
// Private Attributes
|
|
59
|
-
|
|
60
|
-
// Public Static Attributes
|
|
61
|
-
|
|
62
|
-
// Protected Static Attributes
|
|
63
|
-
|
|
64
|
-
// Private Static Attributes
|
|
65
|
-
|
|
66
|
-
// Constructor, Getters, Setters
|
|
67
|
-
|
|
68
|
-
public constructor(public readonly manager: Manager) {}
|
|
69
|
-
|
|
70
|
-
// Public Methods
|
|
71
|
-
|
|
72
|
-
// Protected Methods
|
|
73
|
-
|
|
74
|
-
// Private Methods
|
|
75
|
-
|
|
76
|
-
// Public Static Methods
|
|
77
|
-
|
|
78
|
-
// Protected Static Methods
|
|
99
|
+
public constructor(public readonly manager: M) {}
|
|
79
100
|
|
|
80
|
-
|
|
101
|
+
protected abstract transform<T = Generic>(data: Generic): T
|
|
81
102
|
} //:: class
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
export const DEBUG = 10
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export const INFO = 20
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
export const WARNING = 30
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
export const ERROR = 40
|
|
8
8
|
|
|
9
|
-
|
|
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
|
-
|
|
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
|
package/templates/ctx/index.ts
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
type Generic<T=unknown> = Record<string, T>;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|