@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.
Files changed (69) hide show
  1. package/README.md +57 -22
  2. package/dist/commands/create/project.d.ts +10 -0
  3. package/dist/commands/create/project.js +62 -0
  4. package/dist/commands/generate.d.ts +2 -1
  5. package/dist/commands/generate.js +6 -4
  6. package/dist/commands/initialize.d.ts +4 -3
  7. package/dist/commands/initialize.js +21 -16
  8. package/dist/commands/synchronize.d.ts +6 -5
  9. package/dist/commands/synchronize.js +5 -4
  10. package/dist/internal/CommandHelper.d.ts +4 -0
  11. package/dist/internal/CommandHelper.js +29 -0
  12. package/dist/internal/{CodeGenerationService.d.ts → EntityCodeGenerationService.d.ts} +12 -3
  13. package/dist/internal/{CodeGenerationService.js → EntityCodeGenerationService.js} +69 -19
  14. package/dist/internal/GitChangeDetector.d.ts +24 -0
  15. package/dist/internal/GitChangeDetector.js +119 -0
  16. package/dist/internal/Utils.d.ts +6 -1
  17. package/dist/internal/Utils.js +10 -1
  18. package/dist/internal/converter/IConverterStrategy.d.ts +1 -1
  19. package/dist/internal/converter/codegen/ArrayC3TypeToStatementMapper.d.ts +2 -2
  20. package/dist/internal/converter/codegen/ObjectC3TypeToStatementMapper.d.ts +2 -2
  21. package/dist/internal/converter/codegen/PrimitiveC3TypeToStatementMapper.d.ts +2 -2
  22. package/dist/internal/converter/codegen/StatementMapper.js +1 -1
  23. package/dist/internal/converter/codegen/StatementMapperConversionState.d.ts +1 -1
  24. package/dist/internal/converter/codegen/StatementMapperConversionState.js +1 -1
  25. package/dist/internal/converter/codegen/StatementMapperConverterStrategy.d.ts +3 -3
  26. package/dist/internal/converter/codegen/UnionC3TypeToStatementMapper.d.ts +2 -2
  27. package/dist/internal/converter/codegen/UnionC3TypeToStatementMapper.js +1 -1
  28. package/dist/internal/converter/typescript/ArrayToC3Type.d.ts +2 -2
  29. package/dist/internal/converter/typescript/EnumToC3Type.d.ts +2 -2
  30. package/dist/internal/converter/typescript/ObjectLikeToC3Type.d.ts +2 -2
  31. package/dist/internal/converter/typescript/ObjectLikeToC3Type.js +1 -1
  32. package/dist/internal/converter/typescript/PrimitiveToC3Type.d.ts +1 -1
  33. package/dist/internal/converter/typescript/PrimitiveToC3Type.js +1 -1
  34. package/dist/internal/converter/typescript/QueryOptionsToC3Type.d.ts +2 -2
  35. package/dist/internal/converter/typescript/TenantSelectionToC3Type.d.ts +2 -2
  36. package/dist/internal/converter/typescript/TypescriptConversionState.d.ts +1 -1
  37. package/dist/internal/converter/typescript/TypescriptConversionState.js +1 -1
  38. package/dist/internal/converter/typescript/TypescriptConverterStrategy.d.ts +3 -3
  39. package/dist/internal/converter/typescript/UnionToC3Type.d.ts +2 -2
  40. package/dist/internal/spawn/SpawnConfig.d.ts +31 -0
  41. package/dist/internal/spawn/SpawnConfig.js +12 -0
  42. package/dist/internal/spawn/SpawnEngine.d.ts +27 -0
  43. package/dist/internal/spawn/SpawnEngine.js +187 -0
  44. package/dist/internal/spawn/SpawnResolver.d.ts +17 -0
  45. package/dist/internal/spawn/SpawnResolver.js +14 -0
  46. package/dist/templates/entity/AdminRepository.liquid +14 -0
  47. package/dist/templates/{BaseAdminEntityService.liquid → entity/BaseAdminRepository.liquid} +2 -2
  48. package/dist/templates/{BaseEntityService.liquid → entity/BaseRepository.liquid} +2 -2
  49. package/dist/templates/entity/Repository.liquid +14 -0
  50. package/dist/templates/spawns/library/package.json.liquid +30 -0
  51. package/dist/templates/spawns/library/spawn.json +8 -0
  52. package/dist/templates/spawns/library/src/index.ts +3 -0
  53. package/dist/templates/spawns/library/tsconfig.json +5 -0
  54. package/dist/templates/spawns/project/.config/kinotic.config.ts.liquid +16 -0
  55. package/dist/templates/spawns/project/bunup.config.ts.liquid +11 -0
  56. package/dist/templates/spawns/project/package.json.liquid +22 -0
  57. package/dist/templates/spawns/project/packages/domain/.gitkeep +0 -0
  58. package/dist/templates/spawns/project/packages/domain/model/.gitkeep +0 -0
  59. package/dist/templates/spawns/project/packages/domain/package.json.liquid +34 -0
  60. package/dist/templates/spawns/project/packages/domain/repositories/.gitkeep +0 -0
  61. package/dist/templates/spawns/project/packages/domain/tsconfig.json +5 -0
  62. package/dist/templates/spawns/project/packages/microservices/.gitkeep +0 -0
  63. package/dist/templates/spawns/project/packages/ui/.gitkeep +0 -0
  64. package/dist/templates/spawns/project/spawn.json +11 -0
  65. package/dist/templates/spawns/project/tsconfig.base.json +26 -0
  66. package/oclif.manifest.json +62 -10
  67. package/package.json +19 -10
  68. package/dist/templates/AdminEntityService.liquid +0 -14
  69. package/dist/templates/EntityService.liquid +0 -14
@@ -0,0 +1,187 @@
1
+ import fs from 'node:fs';
2
+ import fsP from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { Liquid } from 'liquidjs';
5
+ import { confirm, input, number, select } from '@inquirer/prompts';
6
+ import { SpawnConfigSchema } from './SpawnConfig.js';
7
+ import { spawnResolver } from './SpawnResolver.js';
8
+ function upperFirst(s) {
9
+ return s.charAt(0).toUpperCase() + s.slice(1);
10
+ }
11
+ function camelCase(s) {
12
+ return s
13
+ .replace(/[-_\s]+(.)/g, (_, c) => c.toUpperCase())
14
+ .replace(/^(.)/, (_, c) => c.toLowerCase());
15
+ }
16
+ export default class SpawnEngine {
17
+ engine;
18
+ spawnResolver;
19
+ constructor(resolver) {
20
+ this.spawnResolver = resolver;
21
+ this.engine = new Liquid({ cache: true });
22
+ this.engine.registerFilter('packageToPath', (v) => v.replaceAll('.', '/'));
23
+ this.engine.registerFilter('encodePackage', (v) => {
24
+ v = v.replaceAll('-', '_');
25
+ v = v.replace(/\.(\d+)/g, '._$1');
26
+ return v;
27
+ });
28
+ this.engine.registerFilter('camelCase', (v) => camelCase(v));
29
+ this.engine.registerFilter('upperFirst', (v) => upperFirst(v));
30
+ }
31
+ /**
32
+ * Renders the specified Spawn
33
+ * A Spawn is a directory that contains templates, an optional spawn.json file, and template parameters in folder and filenames
34
+ *
35
+ * This is done by performing the following
36
+ *
37
+ * - Will recursively walk the spawn copying any files or directories encountered
38
+ * -- If a template file is encountered, it will be parsed and rendered prior to copying
39
+ *
40
+ * @param spawn the name of the spawn to parse and render. This is the name of the directory containing the spawn.json
41
+ * @param destination the target directory where rendered data will be sent
42
+ * @param context the values to be provided to the templates while rendering
43
+ * @return a promise containing all the original values plus any added during rendering
44
+ */
45
+ async renderSpawn(spawn, destination, context) {
46
+ let contextInternal;
47
+ if (!fs.existsSync(destination)) {
48
+ const source = await this.spawnResolver.resolveSpawn(spawn);
49
+ const sources = [source];
50
+ const currentConfigPath = path.resolve(source, 'spawn.json');
51
+ if (fs.existsSync(currentConfigPath)) {
52
+ const spawns = [];
53
+ let currentConfig = currentConfigPath;
54
+ let currentSpawn = SpawnConfigSchema.parse(JSON.parse(fs.readFileSync(currentConfig, { encoding: 'utf8' })));
55
+ spawns.push(currentSpawn);
56
+ // follow inheritance and build stack
57
+ while (currentSpawn.inherits) {
58
+ const inheritDir = path.resolve(path.dirname(currentConfig), currentSpawn.inherits);
59
+ currentConfig = path.resolve(inheritDir, 'spawn.json');
60
+ this.logDebug(`Inheriting from ${currentConfig}\n`);
61
+ if (!fs.existsSync(currentConfig)) {
62
+ throw new Error(`Inherited spawn ${currentConfig} does not exist`);
63
+ }
64
+ currentSpawn = SpawnConfigSchema.parse(JSON.parse(fs.readFileSync(currentConfig, { encoding: 'utf8' })));
65
+ spawns.push(currentSpawn);
66
+ sources.push(inheritDir);
67
+ }
68
+ let globals = {};
69
+ let propertySchemas = {};
70
+ for (const spawnConfig of spawns.reverse()) {
71
+ if (spawnConfig.globals) {
72
+ globals = { ...globals, ...spawnConfig.globals };
73
+ }
74
+ if (spawnConfig.propertySchema) {
75
+ propertySchemas = { ...propertySchemas, ...spawnConfig.propertySchema };
76
+ }
77
+ }
78
+ contextInternal = { ...globals, ...context };
79
+ contextInternal = await this.promptForMissingProperties(propertySchemas, contextInternal);
80
+ }
81
+ await fsP.mkdir(destination, { recursive: true });
82
+ for (const src of sources.reverse()) {
83
+ await this._renderDirectory(src, src, destination, contextInternal);
84
+ }
85
+ return contextInternal;
86
+ }
87
+ else {
88
+ throw new Error(`The target directory ${destination} already exists`);
89
+ }
90
+ }
91
+ async promptForMissingProperties(propertySchema, context) {
92
+ const ret = context ? { ...context } : {};
93
+ let hasPrompted = false;
94
+ for (const key in propertySchema) {
95
+ if (!Object.prototype.hasOwnProperty.call(ret, key)) {
96
+ if (!hasPrompted) {
97
+ console.log('Please provide the following...\n');
98
+ hasPrompted = true;
99
+ }
100
+ const schema = propertySchema[key];
101
+ let message;
102
+ if (schema.description?.includes('{{')) {
103
+ message = this.engine.parseAndRenderSync(schema.description, ret);
104
+ }
105
+ else {
106
+ message = schema.description ?? key;
107
+ }
108
+ let defaultValue;
109
+ if (typeof schema.default === 'string' && schema.default.includes('{{')) {
110
+ defaultValue = this.engine.parseAndRenderSync(schema.default, ret);
111
+ }
112
+ else {
113
+ defaultValue = schema.default;
114
+ }
115
+ if (schema.type === 'boolean') {
116
+ ret[key] = await confirm({ message, default: typeof defaultValue === 'boolean' ? defaultValue : undefined });
117
+ }
118
+ else if (schema.enum) {
119
+ ret[key] = await select({
120
+ message,
121
+ choices: schema.enum.map((v) => ({ value: v })),
122
+ default: defaultValue !== undefined ? String(defaultValue) : undefined
123
+ });
124
+ }
125
+ else if (schema.type === 'number' || schema.type === 'integer') {
126
+ ret[key] = await number({ message, default: typeof defaultValue === 'number' ? defaultValue : undefined });
127
+ }
128
+ else {
129
+ ret[key] = await input({ message, default: typeof defaultValue === 'string' ? defaultValue : undefined });
130
+ }
131
+ }
132
+ }
133
+ return ret;
134
+ }
135
+ async _renderFile(source, destination, errorIfExists, context) {
136
+ if (destination.includes('{{')) {
137
+ destination = await this.engine.parseAndRender(destination, context ?? {});
138
+ }
139
+ let overwritingFile = false;
140
+ if ((errorIfExists) && fs.existsSync(destination)) {
141
+ if (errorIfExists) {
142
+ throw new Error(`The target file ${destination} already exists`);
143
+ }
144
+ overwritingFile = true;
145
+ }
146
+ let readStream;
147
+ if (destination.endsWith('.liquid')) {
148
+ destination = destination.substring(0, destination.length - 7);
149
+ readStream = await this.engine.renderFileToNodeStream(source, context ?? {});
150
+ }
151
+ else {
152
+ readStream = fs.createReadStream(source);
153
+ }
154
+ this.logDebug(`${overwritingFile ? 'Overwriting' : 'Writing'} File\n${source}\nto\n${destination}\n`);
155
+ await fsP.mkdir(path.dirname(destination), { recursive: true });
156
+ const writeStream = fs.createWriteStream(destination);
157
+ readStream.pipe(writeStream);
158
+ }
159
+ async _renderDirectory(baseFrom, from, baseTo, context) {
160
+ const files = await fsP.readdir(from, { withFileTypes: true });
161
+ for (const file of files) {
162
+ const filePath = path.resolve(from, file.name);
163
+ const to = filePath.replace(baseFrom, baseTo);
164
+ if (file.isFile()) {
165
+ if (!this.shouldIgnore(file.name)) {
166
+ await this._renderFile(filePath, to, false, context);
167
+ }
168
+ else {
169
+ this.logDebug(`Skipping File\n${filePath}\n`);
170
+ }
171
+ }
172
+ else {
173
+ await this._renderDirectory(baseFrom, filePath, baseTo, context);
174
+ }
175
+ }
176
+ }
177
+ logDebug(message) {
178
+ if (process.env.DEBUG) {
179
+ console.debug(message);
180
+ }
181
+ }
182
+ shouldIgnore(fileName) {
183
+ const filesToSkip = ['.DS_Store', 'spawn.json'];
184
+ return filesToSkip.includes(fileName);
185
+ }
186
+ }
187
+ export const spawnEngine = new SpawnEngine(spawnResolver);
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Handles resolving "Spawn"s on the local filesystem
3
+ */
4
+ export interface SpawnResolver {
5
+ /**
6
+ * Finds the correct absolute path for the spawn provided.
7
+ *
8
+ * @param spawn the name of desired spawn. Ex: project, library
9
+ * @return a {@link Promise} containing the absolute path or an error if the spawn could not be found
10
+ */
11
+ resolveSpawn(spawn: string): Promise<string>;
12
+ }
13
+ declare class DefaultSpawnResolver implements SpawnResolver {
14
+ resolveSpawn(spawn: string): Promise<string>;
15
+ }
16
+ export declare const spawnResolver: DefaultSpawnResolver;
17
+ export {};
@@ -0,0 +1,14 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'url';
4
+ const bundledTemplatesRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../templates/spawns/');
5
+ class DefaultSpawnResolver {
6
+ async resolveSpawn(spawn) {
7
+ const spawnDir = path.resolve(bundledTemplatesRoot, spawn);
8
+ if (fs.existsSync(spawnDir)) {
9
+ return spawnDir;
10
+ }
11
+ throw new Error(`No spawn could be found with the name ${spawn}`);
12
+ }
13
+ }
14
+ export const spawnResolver = new DefaultSpawnResolver();
@@ -0,0 +1,14 @@
1
+ import { type IAdminEntitiesService } from '@kinotic-ai/persistence'
2
+ import { Base{{ entityName }}AdminRepository } from './generated/Base{{ entityName }}AdminRepository{{ fileExtensionForImports }}'
3
+
4
+ /**
5
+ * Admin Repository for interacting with {{ entityName }} entities
6
+ * This class was generated by the Kinotic CLI
7
+ */
8
+ export class {{ entityName }}AdminRepository extends Base{{ entityName }}AdminRepository {
9
+
10
+ constructor(adminEntitiesService?: IAdminEntitiesService) {
11
+ super(adminEntitiesService)
12
+ }
13
+
14
+ }
@@ -7,10 +7,10 @@ import { {{ entityName }} } from '{{ entityImportPath }}'
7
7
  {{ importStatements }}
8
8
 
9
9
  /**
10
- * Admin Base Service for interacting with {{ entityName }} entities
10
+ * Admin Base Repository for interacting with {{ entityName }} entities
11
11
  * This class was generated by the Kinotic CLI. And will be overwritten if the CLI is run again.
12
12
  */
13
- export class Base{{ entityName }}AdminEntityService extends AdminEntityService<{{ entityName }}> {
13
+ export class Base{{ entityName }}AdminRepository extends AdminEntityService<{{ entityName }}> {
14
14
 
15
15
  constructor(adminEntitiesService?: IAdminEntitiesService) {
16
16
  super('{{ entityNamespace }}', '{{ entityName }}', adminEntitiesService)
@@ -7,10 +7,10 @@ import { {{ entityName }} } from '{{ entityImportPath }}'
7
7
  {{ importStatements }}
8
8
 
9
9
  /**
10
- * Base Service for interacting with {{ entityName }} entities
10
+ * Base Repository for interacting with {{ entityName }} entities
11
11
  * This class was generated by the Kinotic CLI. And will be overwritten if the CLI is run again.
12
12
  */
13
- export class Base{{ entityName }}EntityService extends EntityService<{{ entityName }}> {
13
+ export class Base{{ entityName }}Repository extends EntityService<{{ entityName }}> {
14
14
 
15
15
  private readonly shouldValidate: boolean
16
16
 
@@ -0,0 +1,14 @@
1
+ import { type IEntitiesService } from '@kinotic-ai/persistence'
2
+ import { Base{{ entityName }}Repository } from './generated/Base{{ entityName }}Repository{{ fileExtensionForImports }}'
3
+
4
+ /**
5
+ * Repository for interacting with {{ entityName }} entities
6
+ * This class was generated by the Kinotic CLI
7
+ */
8
+ export class {{ entityName }}Repository extends Base{{ entityName }}Repository {
9
+
10
+ constructor(entitiesService?: IEntitiesService) {
11
+ super({{ validate }}, entitiesService)
12
+ }
13
+
14
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "{{ libraryName }}",
3
+ "version": "0.1.0",
4
+ "files": [
5
+ "dist"
6
+ ],
7
+ "scripts": {
8
+ "type-check": "tsc --noEmit"
9
+ },
10
+ "peerDependencies": {
11
+ "typescript": ">=4.5.0"
12
+ },
13
+ "peerDependenciesMeta": {
14
+ "typescript": {
15
+ "optional": true
16
+ }
17
+ },
18
+ "type": "module",
19
+ "exports": {
20
+ ".": {
21
+ "import": {
22
+ "types": "./dist/index.d.ts",
23
+ "default": "./dist/index.js"
24
+ }
25
+ },
26
+ "./package.json": "./package.json"
27
+ },
28
+ "module": "./dist/index.js",
29
+ "types": "./dist/index.d.ts"
30
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "propertySchema":{
3
+ "libraryName": {
4
+ "type": "string",
5
+ "description": "The name of the library you want to create"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,3 @@
1
+ export function greet(name: string): string {
2
+ return `Hello, ${name}! Welcome to the domain package.`
3
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": { "declaration": true, "isolatedDeclarations": true },
4
+ "include": ["src/**/*"]
5
+ }
@@ -0,0 +1,16 @@
1
+ import type { KinoticProjectConfig } from '@kinotic-ai/core'
2
+
3
+ const config: KinoticProjectConfig = {
4
+ application: "load-testing",
5
+ entitiesPaths: [
6
+ {
7
+ path: "packages/domain/model",
8
+ repositoryPath: "packages/domain/repository",
9
+ mirrorFolderStructure: true
10
+ }
11
+ ],
12
+ fileExtensionForImports: ".js",
13
+ validate: false
14
+ }
15
+
16
+ export default config
@@ -0,0 +1,11 @@
1
+ import { defineWorkspace } from 'bunup'
2
+
3
+ // https://bunup.dev/docs/guide/workspaces
4
+ // You define all your packages for you {{ projectName }} here
5
+
6
+ export default defineWorkspace([
7
+ {
8
+ name: 'domain',
9
+ root: 'packages/domain'
10
+ }
11
+ ])
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "private": true,
4
+ "scripts": {
5
+ "build": "bunup",
6
+ "dev": "bunup --watch",
7
+ "type-check": "bun run --filter '*' type-check"
8
+ },
9
+ "devDependencies": {
10
+ "@types/bun": "^1.3.10",
11
+ "bunup": "^0.16.31",
12
+ "typescript": "^5.9.3"
13
+ },
14
+ "catalog": {
15
+ "@kinotic-ai/core": "{{ kinoticApiVersion }}",
16
+ "@kinotic-ai/persistence": "{{ kinoticApiVersion }}"
17
+ },
18
+ "workspaces": [
19
+ "packages/*"
20
+ ],
21
+ "type": "module"
22
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "{{ projectName }}/domain",
3
+ "version": "0.1.0",
4
+ "files": [
5
+ "dist"
6
+ ],
7
+ "scripts": {
8
+ "type-check": "tsc --noEmit"
9
+ },
10
+ "dependencies": {
11
+ "@kinotic-ai/core": "catalog:",
12
+ "@kinotic-ai/persistence": "catalog:"
13
+ },
14
+ "peerDependencies": {
15
+ "typescript": ">=4.5.0"
16
+ },
17
+ "peerDependenciesMeta": {
18
+ "typescript": {
19
+ "optional": true
20
+ }
21
+ },
22
+ "type": "module",
23
+ "exports": {
24
+ ".": {
25
+ "import": {
26
+ "types": "./dist/index.d.ts",
27
+ "default": "./dist/index.js"
28
+ }
29
+ },
30
+ "./package.json": "./package.json"
31
+ },
32
+ "module": "./dist/index.js",
33
+ "types": "./dist/index.d.ts"
34
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": { "declaration": true, "isolatedDeclarations": true },
4
+ "include": ["src/**/*"]
5
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "globals": {
3
+ "kinoticApiVersion": "^1.0.9"
4
+ },
5
+ "propertySchema":{
6
+ "projectName": {
7
+ "type": "string",
8
+ "description": "The name of the project you want to create"
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": ["ESNext", "DOM"],
4
+ "target": "ES2023",
5
+ "module": "Preserve",
6
+ "moduleDetection": "force",
7
+ "jsx": "react-jsx",
8
+
9
+ "moduleResolution": "bundler",
10
+ "allowImportingTsExtensions": true,
11
+ "verbatimModuleSyntax": true,
12
+ "noEmit": true,
13
+
14
+ "strict": true,
15
+ "skipLibCheck": true,
16
+ "noFallthroughCasesInSwitch": true,
17
+ "noUncheckedIndexedAccess": true,
18
+ "noImplicitOverride": true,
19
+
20
+ "noUnusedLocals": false,
21
+ "noUnusedParameters": false,
22
+ "noPropertyAccessFromIndexSignature": false
23
+ },
24
+
25
+ "exclude": ["node_modules", "dist"]
26
+ }
@@ -5,11 +5,12 @@
5
5
  "gen"
6
6
  ],
7
7
  "args": {},
8
- "description": "This will generate all Entity Service classes.",
8
+ "description": "This will generate all Repository classes.",
9
9
  "examples": [
10
10
  "$ kinotic generate",
11
11
  "$ kinotic gen",
12
- "$ kinotic gen -v"
12
+ "$ kinotic gen -v",
13
+ "$ kinotic gen --force"
13
14
  ],
14
15
  "flags": {
15
16
  "verbose": {
@@ -18,6 +19,13 @@
18
19
  "name": "verbose",
19
20
  "allowNo": false,
20
21
  "type": "boolean"
22
+ },
23
+ "force": {
24
+ "char": "f",
25
+ "description": "Force full regeneration, ignoring incremental change detection",
26
+ "name": "force",
27
+ "allowNo": false,
28
+ "type": "boolean"
21
29
  }
22
30
  },
23
31
  "hasDynamicHelp": false,
@@ -42,9 +50,10 @@
42
50
  "args": {},
43
51
  "description": "This will initialize a new Kinotic Project for use with the Kinotic CLI.",
44
52
  "examples": [
45
- "$ kinotic initialize --application my.app --entities path/to/entities --generated path/to/services",
46
- "$ kinotic init --application my.app --entities path/to/entities --generated path/to/services",
47
- "$ kinotic init -a my.app -e path/to/entities -g path/to/services"
53
+ "$ kinotic initialize --application my.app --entities path/to/entities --repository path/to/repository",
54
+ "$ kinotic init --application my.app --entities path/to/entities --repository path/to/repository",
55
+ "$ kinotic init -a my.app -e path/to/entities -r path/to/repository",
56
+ "$ kinotic init -a my.app -e path/to/entities -r path/to/repository --mirror"
48
57
  ],
49
58
  "flags": {
50
59
  "application": {
@@ -65,14 +74,21 @@
65
74
  "multiple": false,
66
75
  "type": "option"
67
76
  },
68
- "generated": {
69
- "char": "g",
70
- "description": "Path to the directory to write generated Services",
71
- "name": "generated",
77
+ "repository": {
78
+ "char": "r",
79
+ "description": "Path to the directory to write generated Repository classes",
80
+ "name": "repository",
72
81
  "required": false,
73
82
  "hasDynamicHelp": false,
74
83
  "multiple": false,
75
84
  "type": "option"
85
+ },
86
+ "mirror": {
87
+ "char": "m",
88
+ "description": "Mirror the entity folder structure under the repository path",
89
+ "name": "mirror",
90
+ "allowNo": false,
91
+ "type": "boolean"
76
92
  }
77
93
  },
78
94
  "hasDynamicHelp": false,
@@ -139,6 +155,12 @@
139
155
  "name": "dryRun",
140
156
  "allowNo": false,
141
157
  "type": "boolean"
158
+ },
159
+ "force": {
160
+ "description": "Force full regeneration, ignoring incremental change detection",
161
+ "name": "force",
162
+ "allowNo": false,
163
+ "type": "boolean"
142
164
  }
143
165
  },
144
166
  "hasDynamicHelp": false,
@@ -155,7 +177,37 @@
155
177
  "commands",
156
178
  "synchronize.js"
157
179
  ]
180
+ },
181
+ "create:project": {
182
+ "aliases": [],
183
+ "args": {
184
+ "name": {
185
+ "description": "The name for the project",
186
+ "name": "name",
187
+ "required": true
188
+ }
189
+ },
190
+ "description": "Creates a Kinotic Project",
191
+ "examples": [
192
+ "$ kinotic create project MyProjectName"
193
+ ],
194
+ "flags": {},
195
+ "hasDynamicHelp": false,
196
+ "hiddenAliases": [],
197
+ "id": "create:project",
198
+ "pluginAlias": "@kinotic-ai/kinotic-cli",
199
+ "pluginName": "@kinotic-ai/kinotic-cli",
200
+ "pluginType": "core",
201
+ "strict": true,
202
+ "enableJsonFlag": false,
203
+ "isESM": true,
204
+ "relativePath": [
205
+ "dist",
206
+ "commands",
207
+ "create",
208
+ "project.js"
209
+ ]
158
210
  }
159
211
  },
160
- "version": "1.0.2"
212
+ "version": "2.0.0"
161
213
  }