@kinotic-ai/kinotic-cli 1.0.2 → 2.0.0
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/README.md +57 -22
- package/dist/commands/create/project.d.ts +10 -0
- package/dist/commands/create/project.js +62 -0
- package/dist/commands/generate.d.ts +2 -1
- package/dist/commands/generate.js +6 -4
- package/dist/commands/initialize.d.ts +4 -3
- package/dist/commands/initialize.js +21 -16
- package/dist/commands/synchronize.d.ts +6 -5
- package/dist/commands/synchronize.js +5 -4
- package/dist/internal/CommandHelper.d.ts +4 -0
- package/dist/internal/CommandHelper.js +29 -0
- package/dist/internal/{CodeGenerationService.d.ts → EntityCodeGenerationService.d.ts} +12 -3
- package/dist/internal/{CodeGenerationService.js → EntityCodeGenerationService.js} +69 -19
- package/dist/internal/GitChangeDetector.d.ts +24 -0
- package/dist/internal/GitChangeDetector.js +119 -0
- package/dist/internal/Utils.d.ts +6 -1
- package/dist/internal/Utils.js +10 -1
- package/dist/internal/converter/IConverterStrategy.d.ts +1 -1
- package/dist/internal/converter/codegen/ArrayC3TypeToStatementMapper.d.ts +2 -2
- package/dist/internal/converter/codegen/ObjectC3TypeToStatementMapper.d.ts +2 -2
- package/dist/internal/converter/codegen/PrimitiveC3TypeToStatementMapper.d.ts +2 -2
- package/dist/internal/converter/codegen/StatementMapper.js +1 -1
- package/dist/internal/converter/codegen/StatementMapperConversionState.d.ts +1 -1
- package/dist/internal/converter/codegen/StatementMapperConversionState.js +1 -1
- package/dist/internal/converter/codegen/StatementMapperConverterStrategy.d.ts +3 -3
- package/dist/internal/converter/codegen/UnionC3TypeToStatementMapper.d.ts +2 -2
- package/dist/internal/converter/codegen/UnionC3TypeToStatementMapper.js +1 -1
- package/dist/internal/converter/typescript/ArrayToC3Type.d.ts +2 -2
- package/dist/internal/converter/typescript/EnumToC3Type.d.ts +2 -2
- package/dist/internal/converter/typescript/ObjectLikeToC3Type.d.ts +2 -2
- package/dist/internal/converter/typescript/ObjectLikeToC3Type.js +1 -1
- package/dist/internal/converter/typescript/PrimitiveToC3Type.d.ts +1 -1
- package/dist/internal/converter/typescript/PrimitiveToC3Type.js +1 -1
- package/dist/internal/converter/typescript/QueryOptionsToC3Type.d.ts +2 -2
- package/dist/internal/converter/typescript/TenantSelectionToC3Type.d.ts +2 -2
- package/dist/internal/converter/typescript/TypescriptConversionState.d.ts +1 -1
- package/dist/internal/converter/typescript/TypescriptConversionState.js +1 -1
- package/dist/internal/converter/typescript/TypescriptConverterStrategy.d.ts +3 -3
- package/dist/internal/converter/typescript/UnionToC3Type.d.ts +2 -2
- package/dist/internal/spawn/SpawnConfig.d.ts +31 -0
- package/dist/internal/spawn/SpawnConfig.js +12 -0
- package/dist/internal/spawn/SpawnEngine.d.ts +27 -0
- package/dist/internal/spawn/SpawnEngine.js +187 -0
- package/dist/internal/spawn/SpawnResolver.d.ts +17 -0
- package/dist/internal/spawn/SpawnResolver.js +14 -0
- package/dist/templates/entity/AdminRepository.liquid +14 -0
- package/dist/templates/{BaseAdminEntityService.liquid → entity/BaseAdminRepository.liquid} +2 -2
- package/dist/templates/{BaseEntityService.liquid → entity/BaseRepository.liquid} +2 -2
- package/dist/templates/entity/Repository.liquid +14 -0
- package/dist/templates/spawns/library/package.json.liquid +30 -0
- package/dist/templates/spawns/library/spawn.json +8 -0
- package/dist/templates/spawns/library/src/index.ts +3 -0
- package/dist/templates/spawns/library/tsconfig.json +5 -0
- package/dist/templates/spawns/project/.config/kinotic.config.ts.liquid +16 -0
- package/dist/templates/spawns/project/bunup.config.ts.liquid +11 -0
- package/dist/templates/spawns/project/package.json.liquid +22 -0
- package/dist/templates/spawns/project/packages/domain/.gitkeep +0 -0
- package/dist/templates/spawns/project/packages/domain/model/.gitkeep +0 -0
- package/dist/templates/spawns/project/packages/domain/package.json.liquid +34 -0
- package/dist/templates/spawns/project/packages/domain/repositories/.gitkeep +0 -0
- package/dist/templates/spawns/project/packages/domain/tsconfig.json +5 -0
- package/dist/templates/spawns/project/packages/microservices/.gitkeep +0 -0
- package/dist/templates/spawns/project/packages/ui/.gitkeep +0 -0
- package/dist/templates/spawns/project/spawn.json +11 -0
- package/dist/templates/spawns/project/tsconfig.base.json +26 -0
- package/oclif.manifest.json +62 -10
- package/package.json +19 -10
- package/dist/templates/AdminEntityService.liquid +0 -14
- package/dist/templates/EntityService.liquid +0 -14
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ $ npm install -g @kinotic-ai/kinotic-cli
|
|
|
12
12
|
$ kinotic COMMAND
|
|
13
13
|
running command...
|
|
14
14
|
$ kinotic (--version)
|
|
15
|
-
@kinotic-ai/kinotic-cli/
|
|
15
|
+
@kinotic-ai/kinotic-cli/2.0.0 darwin-arm64 node-v22.13.1
|
|
16
16
|
$ kinotic --help [COMMAND]
|
|
17
17
|
USAGE
|
|
18
18
|
$ kinotic COMMAND
|
|
@@ -22,6 +22,7 @@ USAGE
|
|
|
22
22
|
# Commands
|
|
23
23
|
<!-- commands -->
|
|
24
24
|
* [`kinotic autocomplete [SHELL]`](#kinotic-autocomplete-shell)
|
|
25
|
+
* [`kinotic create project NAME`](#kinotic-create-project-name)
|
|
25
26
|
* [`kinotic gen`](#kinotic-gen)
|
|
26
27
|
* [`kinotic generate`](#kinotic-generate)
|
|
27
28
|
* [`kinotic help [COMMAND]`](#kinotic-help-command)
|
|
@@ -72,19 +73,40 @@ EXAMPLES
|
|
|
72
73
|
|
|
73
74
|
_See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v3.2.41/src/commands/autocomplete/index.ts)_
|
|
74
75
|
|
|
76
|
+
## `kinotic create project NAME`
|
|
77
|
+
|
|
78
|
+
Creates a Kinotic Project
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
USAGE
|
|
82
|
+
$ kinotic create project NAME
|
|
83
|
+
|
|
84
|
+
ARGUMENTS
|
|
85
|
+
NAME The name for the project
|
|
86
|
+
|
|
87
|
+
DESCRIPTION
|
|
88
|
+
Creates a Kinotic Project
|
|
89
|
+
|
|
90
|
+
EXAMPLES
|
|
91
|
+
$ kinotic create project MyProjectName
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
_See code: [src/commands/create/project.ts](https://github.com/kinotic-ai/kinotic/blob/v2.0.0/src/commands/create/project.ts)_
|
|
95
|
+
|
|
75
96
|
## `kinotic gen`
|
|
76
97
|
|
|
77
|
-
This will generate all
|
|
98
|
+
This will generate all Repository classes.
|
|
78
99
|
|
|
79
100
|
```
|
|
80
101
|
USAGE
|
|
81
|
-
$ kinotic gen [-v]
|
|
102
|
+
$ kinotic gen [-v] [-f]
|
|
82
103
|
|
|
83
104
|
FLAGS
|
|
105
|
+
-f, --force Force full regeneration, ignoring incremental change detection
|
|
84
106
|
-v, --verbose Enable verbose logging
|
|
85
107
|
|
|
86
108
|
DESCRIPTION
|
|
87
|
-
This will generate all
|
|
109
|
+
This will generate all Repository classes.
|
|
88
110
|
|
|
89
111
|
ALIASES
|
|
90
112
|
$ kinotic gen
|
|
@@ -95,21 +117,24 @@ EXAMPLES
|
|
|
95
117
|
$ kinotic gen
|
|
96
118
|
|
|
97
119
|
$ kinotic gen -v
|
|
120
|
+
|
|
121
|
+
$ kinotic gen --force
|
|
98
122
|
```
|
|
99
123
|
|
|
100
124
|
## `kinotic generate`
|
|
101
125
|
|
|
102
|
-
This will generate all
|
|
126
|
+
This will generate all Repository classes.
|
|
103
127
|
|
|
104
128
|
```
|
|
105
129
|
USAGE
|
|
106
|
-
$ kinotic generate [-v]
|
|
130
|
+
$ kinotic generate [-v] [-f]
|
|
107
131
|
|
|
108
132
|
FLAGS
|
|
133
|
+
-f, --force Force full regeneration, ignoring incremental change detection
|
|
109
134
|
-v, --verbose Enable verbose logging
|
|
110
135
|
|
|
111
136
|
DESCRIPTION
|
|
112
|
-
This will generate all
|
|
137
|
+
This will generate all Repository classes.
|
|
113
138
|
|
|
114
139
|
ALIASES
|
|
115
140
|
$ kinotic gen
|
|
@@ -120,9 +145,11 @@ EXAMPLES
|
|
|
120
145
|
$ kinotic gen
|
|
121
146
|
|
|
122
147
|
$ kinotic gen -v
|
|
148
|
+
|
|
149
|
+
$ kinotic gen --force
|
|
123
150
|
```
|
|
124
151
|
|
|
125
|
-
_See code: [src/commands/generate.ts](https://github.com/kinotic-ai/kinotic/blob/
|
|
152
|
+
_See code: [src/commands/generate.ts](https://github.com/kinotic-ai/kinotic/blob/v2.0.0/src/commands/generate.ts)_
|
|
126
153
|
|
|
127
154
|
## `kinotic help [COMMAND]`
|
|
128
155
|
|
|
@@ -150,12 +177,13 @@ This will initialize a new Kinotic Project for use with the Kinotic CLI.
|
|
|
150
177
|
|
|
151
178
|
```
|
|
152
179
|
USAGE
|
|
153
|
-
$ kinotic init [-a <value>] [-e <value>] [-
|
|
180
|
+
$ kinotic init [-a <value>] [-e <value>] [-r <value>] [-m]
|
|
154
181
|
|
|
155
182
|
FLAGS
|
|
156
183
|
-a, --application=<value> The name of the application you want to use
|
|
157
184
|
-e, --entities=<value> Path to the directory containing the Entity definitions
|
|
158
|
-
-
|
|
185
|
+
-m, --mirror Mirror the entity folder structure under the repository path
|
|
186
|
+
-r, --repository=<value> Path to the directory to write generated Repository classes
|
|
159
187
|
|
|
160
188
|
DESCRIPTION
|
|
161
189
|
This will initialize a new Kinotic Project for use with the Kinotic CLI.
|
|
@@ -164,11 +192,13 @@ ALIASES
|
|
|
164
192
|
$ kinotic init
|
|
165
193
|
|
|
166
194
|
EXAMPLES
|
|
167
|
-
$ kinotic initialize --application my.app --entities path/to/entities --
|
|
195
|
+
$ kinotic initialize --application my.app --entities path/to/entities --repository path/to/repository
|
|
168
196
|
|
|
169
|
-
$ kinotic init --application my.app --entities path/to/entities --
|
|
197
|
+
$ kinotic init --application my.app --entities path/to/entities --repository path/to/repository
|
|
170
198
|
|
|
171
|
-
$ kinotic init -a my.app -e path/to/entities -
|
|
199
|
+
$ kinotic init -a my.app -e path/to/entities -r path/to/repository
|
|
200
|
+
|
|
201
|
+
$ kinotic init -a my.app -e path/to/entities -r path/to/repository --mirror
|
|
172
202
|
```
|
|
173
203
|
|
|
174
204
|
## `kinotic initialize`
|
|
@@ -177,12 +207,13 @@ This will initialize a new Kinotic Project for use with the Kinotic CLI.
|
|
|
177
207
|
|
|
178
208
|
```
|
|
179
209
|
USAGE
|
|
180
|
-
$ kinotic initialize [-a <value>] [-e <value>] [-
|
|
210
|
+
$ kinotic initialize [-a <value>] [-e <value>] [-r <value>] [-m]
|
|
181
211
|
|
|
182
212
|
FLAGS
|
|
183
213
|
-a, --application=<value> The name of the application you want to use
|
|
184
214
|
-e, --entities=<value> Path to the directory containing the Entity definitions
|
|
185
|
-
-
|
|
215
|
+
-m, --mirror Mirror the entity folder structure under the repository path
|
|
216
|
+
-r, --repository=<value> Path to the directory to write generated Repository classes
|
|
186
217
|
|
|
187
218
|
DESCRIPTION
|
|
188
219
|
This will initialize a new Kinotic Project for use with the Kinotic CLI.
|
|
@@ -191,14 +222,16 @@ ALIASES
|
|
|
191
222
|
$ kinotic init
|
|
192
223
|
|
|
193
224
|
EXAMPLES
|
|
194
|
-
$ kinotic initialize --application my.app --entities path/to/entities --
|
|
225
|
+
$ kinotic initialize --application my.app --entities path/to/entities --repository path/to/repository
|
|
226
|
+
|
|
227
|
+
$ kinotic init --application my.app --entities path/to/entities --repository path/to/repository
|
|
195
228
|
|
|
196
|
-
$ kinotic init
|
|
229
|
+
$ kinotic init -a my.app -e path/to/entities -r path/to/repository
|
|
197
230
|
|
|
198
|
-
$ kinotic init -a my.app -e path/to/entities -
|
|
231
|
+
$ kinotic init -a my.app -e path/to/entities -r path/to/repository --mirror
|
|
199
232
|
```
|
|
200
233
|
|
|
201
|
-
_See code: [src/commands/initialize.ts](https://github.com/kinotic-ai/kinotic/blob/
|
|
234
|
+
_See code: [src/commands/initialize.ts](https://github.com/kinotic-ai/kinotic/blob/v2.0.0/src/commands/initialize.ts)_
|
|
202
235
|
|
|
203
236
|
## `kinotic plugins`
|
|
204
237
|
|
|
@@ -496,7 +529,7 @@ Synchronize the local Entity definitions with the Kinotic Server
|
|
|
496
529
|
|
|
497
530
|
```
|
|
498
531
|
USAGE
|
|
499
|
-
$ kinotic sync [-s <value>] [-p] [-v] [-f <value>] [--dryRun]
|
|
532
|
+
$ kinotic sync [-s <value>] [-p] [-v] [-f <value>] [--dryRun] [--force]
|
|
500
533
|
|
|
501
534
|
FLAGS
|
|
502
535
|
-f, --authHeaderFile=<value> JSON File containing authentication headers
|
|
@@ -504,6 +537,7 @@ FLAGS
|
|
|
504
537
|
-s, --server=<value> The Kinotic server to connect to
|
|
505
538
|
-v, --verbose Enable verbose logging
|
|
506
539
|
--dryRun Dry run enables verbose logging and does not save any changes to the server
|
|
540
|
+
--force Force full regeneration, ignoring incremental change detection
|
|
507
541
|
|
|
508
542
|
DESCRIPTION
|
|
509
543
|
Synchronize the local Entity definitions with the Kinotic Server
|
|
@@ -527,7 +561,7 @@ Synchronize the local Entity definitions with the Kinotic Server
|
|
|
527
561
|
|
|
528
562
|
```
|
|
529
563
|
USAGE
|
|
530
|
-
$ kinotic synchronize [-s <value>] [-p] [-v] [-f <value>] [--dryRun]
|
|
564
|
+
$ kinotic synchronize [-s <value>] [-p] [-v] [-f <value>] [--dryRun] [--force]
|
|
531
565
|
|
|
532
566
|
FLAGS
|
|
533
567
|
-f, --authHeaderFile=<value> JSON File containing authentication headers
|
|
@@ -535,6 +569,7 @@ FLAGS
|
|
|
535
569
|
-s, --server=<value> The Kinotic server to connect to
|
|
536
570
|
-v, --verbose Enable verbose logging
|
|
537
571
|
--dryRun Dry run enables verbose logging and does not save any changes to the server
|
|
572
|
+
--force Force full regeneration, ignoring incremental change detection
|
|
538
573
|
|
|
539
574
|
DESCRIPTION
|
|
540
575
|
Synchronize the local Entity definitions with the Kinotic Server
|
|
@@ -552,7 +587,7 @@ EXAMPLES
|
|
|
552
587
|
$ kinotic sync -p -v -s http://localhost:9090
|
|
553
588
|
```
|
|
554
589
|
|
|
555
|
-
_See code: [src/commands/synchronize.ts](https://github.com/kinotic-ai/kinotic/blob/
|
|
590
|
+
_See code: [src/commands/synchronize.ts](https://github.com/kinotic-ai/kinotic/blob/v2.0.0/src/commands/synchronize.ts)_
|
|
556
591
|
|
|
557
592
|
## `kinotic update [CHANNEL]`
|
|
558
593
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export declare class Project extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
name: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
private renderProjectModule;
|
|
10
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Args, Command } from '@oclif/core';
|
|
2
|
+
import { input, select } from '@inquirer/prompts';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import process from 'node:process';
|
|
7
|
+
import { spawnEngine } from '../../internal/spawn/SpawnEngine.js';
|
|
8
|
+
import { createFrontEnd } from '../../internal/CommandHelper.js';
|
|
9
|
+
export class Project extends Command {
|
|
10
|
+
static description = 'Creates a Kinotic Project';
|
|
11
|
+
static examples = [
|
|
12
|
+
'$ kinotic create project MyProjectName',
|
|
13
|
+
];
|
|
14
|
+
static args = {
|
|
15
|
+
name: Args.string({ description: 'The name for the project', required: true })
|
|
16
|
+
};
|
|
17
|
+
async run() {
|
|
18
|
+
const { args } = await this.parse(Project);
|
|
19
|
+
const projectDir = path.resolve(args.name);
|
|
20
|
+
let context = { projectName: args.name };
|
|
21
|
+
this.log(chalk.cyan('Creating Kinotic Project'));
|
|
22
|
+
const spinner = ora('Generating project...').start();
|
|
23
|
+
try {
|
|
24
|
+
context = (await spawnEngine.renderSpawn('project', projectDir, context)) ?? context;
|
|
25
|
+
spinner.succeed(chalk.green('Project generated'));
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
spinner.fail('Project generation failed');
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
31
|
+
process.chdir(projectDir);
|
|
32
|
+
let choice;
|
|
33
|
+
do {
|
|
34
|
+
choice = await select({
|
|
35
|
+
message: 'What would you like to add?',
|
|
36
|
+
choices: [{ value: 'Library' }, { value: 'Frontend' }, { value: 'Quit' }]
|
|
37
|
+
});
|
|
38
|
+
switch (choice) {
|
|
39
|
+
case 'Library': {
|
|
40
|
+
const libraryName = await input({ message: 'Library Name' });
|
|
41
|
+
context.libraryName = libraryName;
|
|
42
|
+
await this.renderProjectModule('library', libraryName, projectDir, context);
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
case 'Frontend': {
|
|
46
|
+
const name = await input({ message: 'Project Name' });
|
|
47
|
+
await createFrontEnd(name);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
case 'Quit':
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
} while (choice !== 'Quit');
|
|
54
|
+
}
|
|
55
|
+
async renderProjectModule(spawn, name, projectDir, context) {
|
|
56
|
+
const dir = path.resolve(name);
|
|
57
|
+
if (!dir.startsWith(projectDir)) {
|
|
58
|
+
throw new Error(`Module dir ${dir} must be within ${projectDir}`);
|
|
59
|
+
}
|
|
60
|
+
await spawnEngine.renderSpawn(spawn, dir, context);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -4,7 +4,8 @@ export declare class Generate extends Command {
|
|
|
4
4
|
static description: string;
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static flags: {
|
|
7
|
-
verbose: import("@oclif/core/lib/interfaces
|
|
7
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
8
9
|
};
|
|
9
10
|
run(): Promise<void>;
|
|
10
11
|
logVerbose(message: string | (() => string), verbose: boolean): void;
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EntityCodeGenerationService } from '../internal/EntityCodeGenerationService.js';
|
|
2
2
|
import { Command, Flags } from '@oclif/core';
|
|
3
3
|
import { isKinoticProject, loadKinoticProjectConfig } from '../internal/state/KinoticProjectConfigUtil.js';
|
|
4
4
|
export class Generate extends Command {
|
|
5
5
|
static aliases = ['gen'];
|
|
6
|
-
static description = 'This will generate all
|
|
6
|
+
static description = 'This will generate all Repository classes.';
|
|
7
7
|
static examples = [
|
|
8
8
|
'$ kinotic generate',
|
|
9
9
|
'$ kinotic gen',
|
|
10
10
|
'$ kinotic gen -v',
|
|
11
|
+
'$ kinotic gen --force',
|
|
11
12
|
];
|
|
12
13
|
static flags = {
|
|
13
14
|
verbose: Flags.boolean({ char: 'v', description: 'Enable verbose logging', default: false }),
|
|
15
|
+
force: Flags.boolean({ char: 'f', description: 'Force full regeneration, ignoring incremental change detection', default: false }),
|
|
14
16
|
};
|
|
15
17
|
async run() {
|
|
16
18
|
const { flags } = await this.parse(Generate);
|
|
@@ -18,8 +20,8 @@ export class Generate extends Command {
|
|
|
18
20
|
this.error('The working directory is not a Kinotic Project');
|
|
19
21
|
}
|
|
20
22
|
const kinoticProjectConfig = await loadKinoticProjectConfig();
|
|
21
|
-
const codeGenerationService = new
|
|
22
|
-
await codeGenerationService.generateAllEntities(kinoticProjectConfig, flags.verbose);
|
|
23
|
+
const codeGenerationService = new EntityCodeGenerationService(kinoticProjectConfig.application, kinoticProjectConfig.fileExtensionForImports, this);
|
|
24
|
+
await codeGenerationService.generateAllEntities(kinoticProjectConfig, flags.verbose, undefined, flags.force);
|
|
23
25
|
this.log(`Code Generation Complete For application: ${kinoticProjectConfig.application}`);
|
|
24
26
|
}
|
|
25
27
|
// This is needed for the CodeGenerationService to log verbose messages
|
|
@@ -4,9 +4,10 @@ export declare class Initialize extends Command {
|
|
|
4
4
|
static description: string;
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static flags: {
|
|
7
|
-
application: import("@oclif/core/lib/interfaces
|
|
8
|
-
entities: import("@oclif/core/lib/interfaces
|
|
9
|
-
|
|
7
|
+
application: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
entities: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
|
+
repository: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
|
+
mirror: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
11
|
};
|
|
11
12
|
run(): Promise<void>;
|
|
12
13
|
}
|
|
@@ -28,14 +28,16 @@ export class Initialize extends Command {
|
|
|
28
28
|
static aliases = ['init'];
|
|
29
29
|
static description = 'This will initialize a new Kinotic Project for use with the Kinotic CLI.';
|
|
30
30
|
static examples = [
|
|
31
|
-
'$ kinotic initialize --application my.app --entities path/to/entities --
|
|
32
|
-
'$ kinotic init --application my.app --entities path/to/entities --
|
|
33
|
-
'$ kinotic init -a my.app -e path/to/entities -
|
|
31
|
+
'$ kinotic initialize --application my.app --entities path/to/entities --repository path/to/repository',
|
|
32
|
+
'$ kinotic init --application my.app --entities path/to/entities --repository path/to/repository',
|
|
33
|
+
'$ kinotic init -a my.app -e path/to/entities -r path/to/repository',
|
|
34
|
+
'$ kinotic init -a my.app -e path/to/entities -r path/to/repository --mirror',
|
|
34
35
|
];
|
|
35
36
|
static flags = {
|
|
36
37
|
application: Flags.string({ char: 'a', description: 'The name of the application you want to use', required: false }),
|
|
37
38
|
entities: Flags.string({ char: 'e', description: 'Path to the directory containing the Entity definitions', required: false }),
|
|
38
|
-
|
|
39
|
+
repository: Flags.string({ char: 'r', description: 'Path to the directory to write generated Repository classes', required: false }),
|
|
40
|
+
mirror: Flags.boolean({ char: 'm', description: 'Mirror the entity folder structure under the repository path', default: true }),
|
|
39
41
|
};
|
|
40
42
|
async run() {
|
|
41
43
|
const { flags } = await this.parse(Initialize);
|
|
@@ -67,33 +69,36 @@ export class Initialize extends Command {
|
|
|
67
69
|
if (!entitiesPath) {
|
|
68
70
|
entitiesPath = await input({
|
|
69
71
|
message: 'Path to the directory containing Entity definitions:',
|
|
70
|
-
default: 'src/
|
|
72
|
+
default: 'src/model',
|
|
71
73
|
validate: (input) => input.trim() !== '' || 'Entities path is required'
|
|
72
74
|
});
|
|
73
75
|
}
|
|
74
|
-
let
|
|
75
|
-
if (!
|
|
76
|
-
|
|
77
|
-
message: 'Path to the directory to write generated
|
|
78
|
-
default: 'src/
|
|
79
|
-
validate: (input) => input.trim() !== '' || '
|
|
76
|
+
let repositoryPath = flags.repository;
|
|
77
|
+
if (!repositoryPath) {
|
|
78
|
+
repositoryPath = await input({
|
|
79
|
+
message: 'Path to the directory to write generated Repository classes:',
|
|
80
|
+
default: 'src/repository',
|
|
81
|
+
validate: (input) => input.trim() !== '' || 'Repository path is required'
|
|
80
82
|
});
|
|
81
83
|
}
|
|
82
84
|
const entitiesAbsPath = path.resolve(entitiesPath);
|
|
83
|
-
const
|
|
85
|
+
const repositoryAbsPath = path.resolve(repositoryPath);
|
|
84
86
|
if (!fs.existsSync(entitiesAbsPath)) {
|
|
85
87
|
this.error(`Entities path does not exist: ${entitiesAbsPath}`);
|
|
86
88
|
}
|
|
87
|
-
if (!fs.existsSync(
|
|
88
|
-
this.error(`
|
|
89
|
+
if (!fs.existsSync(repositoryAbsPath)) {
|
|
90
|
+
this.error(`Repository path does not exist: ${repositoryAbsPath}`);
|
|
89
91
|
}
|
|
90
92
|
// Only use TypescriptProjectConfig for initialization
|
|
91
93
|
const configDir = path.resolve(process.cwd(), '.config');
|
|
92
94
|
const configObj = new KinoticProjectConfig();
|
|
93
95
|
// Don't set name - it will be loaded from package.json
|
|
94
96
|
configObj.application = application;
|
|
95
|
-
configObj.entitiesPaths = [
|
|
96
|
-
|
|
97
|
+
configObj.entitiesPaths = [{
|
|
98
|
+
path: entitiesPath,
|
|
99
|
+
repositoryPath: repositoryPath,
|
|
100
|
+
mirrorFolderStructure: flags.mirror
|
|
101
|
+
}];
|
|
97
102
|
configObj.validate = false;
|
|
98
103
|
configObj.fileExtensionForImports = '.js';
|
|
99
104
|
await saveKinoticProjectConfig(configObj, configDir);
|
|
@@ -4,11 +4,12 @@ export declare class Synchronize extends Command {
|
|
|
4
4
|
static description: string;
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static flags: {
|
|
7
|
-
server: import("@oclif/core/lib/interfaces
|
|
8
|
-
publish: import("@oclif/core/lib/interfaces
|
|
9
|
-
verbose: import("@oclif/core/lib/interfaces
|
|
10
|
-
authHeaderFile: import("@oclif/core/lib/interfaces
|
|
11
|
-
dryRun: import("@oclif/core/lib/interfaces
|
|
7
|
+
server: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
publish: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
authHeaderFile: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
dryRun: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
13
|
};
|
|
13
14
|
run(): Promise<void>;
|
|
14
15
|
logVerbose(message: string | (() => string), verbose: boolean): void;
|
|
@@ -4,7 +4,7 @@ import { EntityDefinition, NamedQueriesDefinition, OsApiPlugin, Project, Project
|
|
|
4
4
|
import { Command, Flags } from '@oclif/core';
|
|
5
5
|
import chalk from 'chalk';
|
|
6
6
|
import { WebSocket } from 'ws';
|
|
7
|
-
import {
|
|
7
|
+
import { EntityCodeGenerationService } from '../internal/EntityCodeGenerationService.js';
|
|
8
8
|
import { ProjectMigrationService } from '../internal/ProjectMigrationService.js';
|
|
9
9
|
import { resolveServer } from '../internal/state/Environment.js';
|
|
10
10
|
import { connectAndUpgradeSession } from '../internal/Utils.js';
|
|
@@ -25,7 +25,8 @@ export class Synchronize extends Command {
|
|
|
25
25
|
publish: Flags.boolean({ char: 'p', description: 'Publish each Entity after save/update' }),
|
|
26
26
|
verbose: Flags.boolean({ char: 'v', description: 'Enable verbose logging' }),
|
|
27
27
|
authHeaderFile: Flags.string({ char: 'f', description: 'JSON File containing authentication headers', required: false }),
|
|
28
|
-
dryRun: Flags.boolean({ description: 'Dry run enables verbose logging and does not save any changes to the server' })
|
|
28
|
+
dryRun: Flags.boolean({ description: 'Dry run enables verbose logging and does not save any changes to the server' }),
|
|
29
|
+
force: Flags.boolean({ description: 'Force full regeneration, ignoring incremental change detection', default: false })
|
|
29
30
|
};
|
|
30
31
|
async run() {
|
|
31
32
|
const { flags } = await this.parse(Synchronize);
|
|
@@ -48,7 +49,7 @@ export class Synchronize extends Command {
|
|
|
48
49
|
project.sourceOfTruth = ProjectType.TYPESCRIPT;
|
|
49
50
|
project = await Kinotic.projects.createProjectIfNotExist(project);
|
|
50
51
|
}
|
|
51
|
-
const codeGenerationService = new
|
|
52
|
+
const codeGenerationService = new EntityCodeGenerationService(kinoticProjectConfig.application, kinoticProjectConfig.fileExtensionForImports, this);
|
|
52
53
|
await codeGenerationService
|
|
53
54
|
.generateAllEntities(kinoticProjectConfig, flags.verbose || flags.dryRun, async (entityInfo, services) => {
|
|
54
55
|
// combine named queries from generated services
|
|
@@ -66,7 +67,7 @@ export class Synchronize extends Command {
|
|
|
66
67
|
if (!flags.dryRun) {
|
|
67
68
|
await this.synchronizeEntity(project.id, entityInfo.entity, flags.publish, flags.verbose);
|
|
68
69
|
}
|
|
69
|
-
});
|
|
70
|
+
}, flags.force);
|
|
70
71
|
// Apply migrations after entity synchronization
|
|
71
72
|
if (!flags.dryRun) {
|
|
72
73
|
const migrationService = new ProjectMigrationService(this);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { select } from '@inquirer/prompts';
|
|
2
|
+
import { execa } from 'execa';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a new front end project using either React or Vue depending on the user's choice
|
|
5
|
+
*/
|
|
6
|
+
export async function createFrontEnd(name) {
|
|
7
|
+
const framework = await select({
|
|
8
|
+
message: 'Which framework would you like to use?',
|
|
9
|
+
choices: [{ value: 'React' }, { value: 'Vue' }]
|
|
10
|
+
});
|
|
11
|
+
if (framework === 'React') {
|
|
12
|
+
await createReact(name);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
await createVue(name);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new React project using create-react-app
|
|
20
|
+
*/
|
|
21
|
+
async function createReact(name) {
|
|
22
|
+
await execa('npx', ['create-react-app', name], { stdio: 'inherit' });
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Creates a new Vue project using vue-cli with npx
|
|
26
|
+
*/
|
|
27
|
+
async function createVue(name) {
|
|
28
|
+
await execa('npx', ['@vue/cli', 'create', name], { stdio: 'inherit' });
|
|
29
|
+
}
|
|
@@ -5,16 +5,25 @@ export type GeneratedEntityProcessor = (entityInfo: EntityInfo, serviceInfo: Gen
|
|
|
5
5
|
/**
|
|
6
6
|
* Helper service for generating code.s
|
|
7
7
|
*/
|
|
8
|
-
export declare class
|
|
8
|
+
export declare class EntityCodeGenerationService {
|
|
9
9
|
private readonly fileExtensionForImports;
|
|
10
10
|
private readonly logger;
|
|
11
11
|
private readonly engine;
|
|
12
12
|
private readonly tsMorphProject;
|
|
13
13
|
private readonly conversionContext;
|
|
14
14
|
constructor(application: string, fileExtensionForImports: string, logger: Logger);
|
|
15
|
-
generateAllEntities(projectConfig: KinoticProjectConfig, verbose: boolean, entityProcessor?: GeneratedEntityProcessor): Promise<void>;
|
|
15
|
+
generateAllEntities(projectConfig: KinoticProjectConfig, verbose: boolean, entityProcessor?: GeneratedEntityProcessor, force?: boolean): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Normalizes an entitiesPaths entry into a fully resolved {@link EntitiesPathConfig}.
|
|
18
|
+
*/
|
|
19
|
+
private resolveEntitiesPathConfig;
|
|
16
20
|
private processEntities;
|
|
17
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Resolves the output path for generated repository files based on the entity's source location
|
|
23
|
+
* and the path configuration.
|
|
24
|
+
*/
|
|
25
|
+
private resolveRepositoryOutputPath;
|
|
26
|
+
private generateRepository;
|
|
18
27
|
/**
|
|
19
28
|
* Adds invocation logic to named queries and returns the {@link FunctionDefinition}s that define them.
|
|
20
29
|
*/
|