@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
@@ -12,11 +12,12 @@ import { tsDecoratorToC3Decorator } from './converter/typescript/ConverterUtils.
12
12
  import { TypescriptConversionState } from './converter/typescript/TypescriptConversionState.js';
13
13
  import { TypescriptConverterStrategy } from './converter/typescript/TypescriptConverterStrategy.js';
14
14
  import { convertAllEntities, createTsMorphProject, getRelativeImportPath, tryGetNodeModuleName, writeEntityJsonToFilesystem, writeGeneratedServiceInfoToFilesystem } from './Utils.js';
15
+ import { GitChangeDetector } from './GitChangeDetector.js';
15
16
  import chalk from 'chalk';
16
17
  /**
17
18
  * Helper service for generating code.s
18
19
  */
19
- export class CodeGenerationService {
20
+ export class EntityCodeGenerationService {
20
21
  fileExtensionForImports;
21
22
  logger;
22
23
  engine;
@@ -34,35 +35,70 @@ export class CodeGenerationService {
34
35
  state.shouldAddSourcePathToMetadata = false;
35
36
  this.conversionContext = createConversionContext(new TypescriptConverterStrategy(state, logger));
36
37
  }
37
- async generateAllEntities(projectConfig, verbose, entityProcessor) {
38
- for (const entitiesPath of projectConfig.entitiesPaths) {
38
+ async generateAllEntities(projectConfig, verbose, entityProcessor, force = false) {
39
+ const changeDetector = new GitChangeDetector(this.logger);
40
+ // Resolve all entity paths for change detection
41
+ const resolvedConfigs = projectConfig.entitiesPaths.map(entry => this.resolveEntitiesPathConfig(entry, projectConfig));
42
+ const allEntitiesPaths = resolvedConfigs.map(c => c.path);
43
+ // Determine which files have changed (null means full scan)
44
+ const changedFiles = force ? null : await changeDetector.getChangedEntityFiles(allEntitiesPaths);
45
+ if (changedFiles !== null && changedFiles.size === 0) {
46
+ this.logger.log('No entity files changed since last generation, skipping');
47
+ return;
48
+ }
49
+ if (changedFiles !== null) {
50
+ this.logger.log(`Incremental generation: ${changedFiles.size} changed file(s) detected`);
51
+ }
52
+ for (const resolvedPathConfig of resolvedConfigs) {
39
53
  const config = {
40
54
  application: projectConfig.application,
41
- entitiesPath: entitiesPath,
55
+ entitiesPath: resolvedPathConfig.path,
42
56
  verbose: verbose,
43
57
  logger: this.logger
44
58
  };
45
- await this.processEntities(config, projectConfig, entityProcessor);
59
+ await this.processEntities(config, projectConfig, resolvedPathConfig, changedFiles, entityProcessor);
60
+ }
61
+ await changeDetector.saveLastGenerationHash();
62
+ }
63
+ /**
64
+ * Normalizes an entitiesPaths entry into a fully resolved {@link EntitiesPathConfig}.
65
+ */
66
+ resolveEntitiesPathConfig(entry, projectConfig) {
67
+ if (typeof entry === 'string') {
68
+ if (!projectConfig.generatedPath) {
69
+ throw new Error(`entitiesPaths contains a plain string "${entry}" but no generatedPath is configured. `
70
+ + `Either use an EntitiesPathConfig object or set generatedPath.`);
71
+ }
72
+ return {
73
+ path: entry,
74
+ repositoryPath: projectConfig.generatedPath,
75
+ mirrorFolderStructure: false
76
+ };
46
77
  }
78
+ return {
79
+ ...entry,
80
+ mirrorFolderStructure: entry.mirrorFolderStructure ?? true
81
+ };
47
82
  }
48
- async processEntities(config, projectConfig, entityProcessor) {
83
+ async processEntities(config, projectConfig, pathConfig, changedFiles, entityProcessor) {
49
84
  if (!fs.existsSync(config.entitiesPath)) {
50
85
  throw new Error(`Entities path does not exist: ${config.entitiesPath}`);
51
86
  }
52
- const convertedEntities = convertAllEntities(config);
87
+ const convertedEntities = convertAllEntities(config, changedFiles);
53
88
  if (convertedEntities.length > 0) {
54
89
  for (const entityInfo of convertedEntities) {
55
90
  this.logger.logVerbose(`Generated Persistence Mapping for ${entityInfo.entity.namespace}.${entityInfo.entity.name}`, config.verbose);
91
+ const repositoryOutputPath = this.resolveRepositoryOutputPath(entityInfo, pathConfig);
56
92
  const generatedServices = [];
57
- generatedServices.push(await this.generateEntityService(false, entityInfo, projectConfig));
93
+ generatedServices.push(await this.generateRepository(false, entityInfo, projectConfig, repositoryOutputPath));
58
94
  if (entityInfo.multiTenantSelectionEnabled) {
59
- generatedServices.push(await this.generateEntityService(true, entityInfo, projectConfig));
95
+ generatedServices.push(await this.generateRepository(true, entityInfo, projectConfig, repositoryOutputPath));
60
96
  }
61
97
  if (config.verbose) {
62
- await writeEntityJsonToFilesystem(projectConfig.generatedPath, entityInfo.entity, this.logger);
98
+ await writeEntityJsonToFilesystem(repositoryOutputPath, entityInfo.entity, this.logger);
63
99
  for (let generatedServiceInfo of generatedServices) {
64
100
  if (generatedServiceInfo.namedQueries.length > 0) {
65
- await writeGeneratedServiceInfoToFilesystem(projectConfig.generatedPath, generatedServiceInfo, this.logger);
101
+ await writeGeneratedServiceInfoToFilesystem(repositoryOutputPath, generatedServiceInfo, this.logger);
66
102
  }
67
103
  }
68
104
  }
@@ -75,12 +111,26 @@ export class CodeGenerationService {
75
111
  this.logger.logVerbose(`No Entities found For namespace: ${config.application} and Entities Path: ${config.entitiesPath}`, config.verbose);
76
112
  }
77
113
  }
78
- async generateEntityService(adminService, entityInfo, projectConfig) {
114
+ /**
115
+ * Resolves the output path for generated repository files based on the entity's source location
116
+ * and the path configuration.
117
+ */
118
+ resolveRepositoryOutputPath(entityInfo, pathConfig) {
119
+ const absEntitiesPath = path.resolve(pathConfig.path);
120
+ const absRepositoryPath = path.resolve(pathConfig.repositoryPath);
121
+ if (pathConfig.mirrorFolderStructure) {
122
+ // Compute the entity's relative directory within the entities path
123
+ const absEntityDir = path.dirname(path.resolve(entityInfo.exportedFromFile));
124
+ const relativeDir = path.relative(absEntitiesPath, absEntityDir);
125
+ return path.resolve(absRepositoryPath, relativeDir);
126
+ }
127
+ return absRepositoryPath;
128
+ }
129
+ async generateRepository(adminService, entityInfo, projectConfig, repositoryOutputPath) {
79
130
  const adminPrefix = (adminService ? 'Admin' : '');
80
131
  const fileExtensionForImports = this.fileExtensionForImports;
81
- const generatedPath = projectConfig.generatedPath;
82
- const baseEntityServicePath = path.resolve(generatedPath, 'generated', `Base${entityInfo.entity.name}${adminPrefix}EntityService.ts`);
83
- const entityServicePath = path.resolve(generatedPath, `${entityInfo.entity.name}${adminPrefix}EntityService.ts`);
132
+ const baseEntityServicePath = path.resolve(repositoryOutputPath, 'generated', `Base${entityInfo.entity.name}${adminPrefix}Repository.ts`);
133
+ const entityServicePath = path.resolve(repositoryOutputPath, `${entityInfo.entity.name}${adminPrefix}Repository.ts`);
84
134
  const entityName = entityInfo.entity.name;
85
135
  const entityNamespace = entityInfo.entity.namespace;
86
136
  const defaultExport = entityInfo.defaultExport;
@@ -99,7 +149,7 @@ export class CodeGenerationService {
99
149
  const importStatements = createImportString(statement, baseEntityServicePath, fileExtensionForImports) || '';
100
150
  // We always generate the base entity service. This way if our internal logic changes we can update it
101
151
  fs.mkdirSync(path.dirname(baseEntityServicePath), { recursive: true });
102
- const baseReadStream = await this.engine.renderFileToNodeStream(`Base${adminPrefix}EntityService`, {
152
+ const baseReadStream = await this.engine.renderFileToNodeStream(`Base${adminPrefix}Repository`, {
103
153
  entityName,
104
154
  entityNamespace,
105
155
  defaultExport,
@@ -112,7 +162,7 @@ export class CodeGenerationService {
112
162
  // we only generate if the file does not exist
113
163
  let namedQueries = [];
114
164
  if (!fs.existsSync(entityServicePath)) {
115
- const readStream = await this.engine.renderFileToNodeStream(`${adminPrefix}EntityService`, {
165
+ const readStream = await this.engine.renderFileToNodeStream(`${adminPrefix}Repository`, {
116
166
  entityName,
117
167
  entityNamespace,
118
168
  validate,
@@ -123,10 +173,10 @@ export class CodeGenerationService {
123
173
  }
124
174
  else {
125
175
  // if it already exists we check if there are any named queries defined
126
- namedQueries = await this.processNamedQueries(`${entityName}${adminPrefix}EntityService`, entityServicePath);
176
+ namedQueries = await this.processNamedQueries(`${entityName}${adminPrefix}Repository`, entityServicePath);
127
177
  }
128
178
  return {
129
- entityServiceName: `${entityName}${adminPrefix}EntityService`,
179
+ entityServiceName: `${entityName}${adminPrefix}Repository`,
130
180
  namedQueries: namedQueries
131
181
  };
132
182
  }
@@ -0,0 +1,24 @@
1
+ import { Logger } from './Logger.js';
2
+ /**
3
+ * Detects changed files within entity paths using git.
4
+ * Stores the commit hash of the last successful generation to determine
5
+ * which files have changed since then.
6
+ */
7
+ export declare class GitChangeDetector {
8
+ private readonly logger;
9
+ private readonly git;
10
+ constructor(logger: Logger);
11
+ /**
12
+ * Returns the set of absolute file paths that have changed within the given entity paths
13
+ * since the last generation, or null if a full scan is needed (no git, first run, etc.).
14
+ */
15
+ getChangedEntityFiles(entitiesPaths: string[]): Promise<Set<string> | null>;
16
+ /**
17
+ * Saves the current HEAD commit hash as the last generation point.
18
+ */
19
+ saveLastGenerationHash(): Promise<void>;
20
+ private readLastGenerationHash;
21
+ private isGitRepo;
22
+ private isValidCommit;
23
+ private addFiles;
24
+ }
@@ -0,0 +1,119 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import simpleGit from 'simple-git';
4
+ const LAST_GENERATION_FILE = '.kinotic/last-generation';
5
+ /**
6
+ * Detects changed files within entity paths using git.
7
+ * Stores the commit hash of the last successful generation to determine
8
+ * which files have changed since then.
9
+ */
10
+ export class GitChangeDetector {
11
+ logger;
12
+ git;
13
+ constructor(logger) {
14
+ this.logger = logger;
15
+ this.git = simpleGit();
16
+ }
17
+ /**
18
+ * Returns the set of absolute file paths that have changed within the given entity paths
19
+ * since the last generation, or null if a full scan is needed (no git, first run, etc.).
20
+ */
21
+ async getChangedEntityFiles(entitiesPaths) {
22
+ if (!(await this.isGitRepo())) {
23
+ this.logger.log('Not a git repository, performing full scan');
24
+ return null;
25
+ }
26
+ const lastHash = this.readLastGenerationHash();
27
+ if (!lastHash) {
28
+ this.logger.log('No previous generation found, performing full scan');
29
+ return null;
30
+ }
31
+ // Verify the stored hash still exists in git history
32
+ if (!(await this.isValidCommit(lastHash))) {
33
+ this.logger.log('Previous generation commit no longer exists, performing full scan');
34
+ return null;
35
+ }
36
+ const changedFiles = new Set();
37
+ // Files changed between last generation commit and HEAD
38
+ const committedDiff = await this.git.diff(['--name-only', lastHash, 'HEAD']);
39
+ this.addFiles(changedFiles, committedDiff);
40
+ // Unstaged changes in working tree
41
+ const unstagedDiff = await this.git.diff(['--name-only']);
42
+ this.addFiles(changedFiles, unstagedDiff);
43
+ // Staged but not committed changes
44
+ const stagedDiff = await this.git.diff(['--cached', '--name-only']);
45
+ this.addFiles(changedFiles, stagedDiff);
46
+ // New untracked files
47
+ const statusResult = await this.git.status();
48
+ for (const file of statusResult.not_added) {
49
+ changedFiles.add(path.resolve(file));
50
+ }
51
+ // Filter to only .ts files within entity paths
52
+ const absEntitiesPaths = entitiesPaths.map(p => {
53
+ const abs = path.resolve(p);
54
+ return abs.endsWith(path.sep) ? abs : abs + path.sep;
55
+ });
56
+ const relevantFiles = new Set();
57
+ for (const file of changedFiles) {
58
+ for (const entitiesPath of absEntitiesPaths) {
59
+ if (file.startsWith(entitiesPath) && file.endsWith('.ts')) {
60
+ relevantFiles.add(file);
61
+ break;
62
+ }
63
+ }
64
+ }
65
+ return relevantFiles;
66
+ }
67
+ /**
68
+ * Saves the current HEAD commit hash as the last generation point.
69
+ */
70
+ async saveLastGenerationHash() {
71
+ if (!(await this.isGitRepo())) {
72
+ return;
73
+ }
74
+ try {
75
+ const hash = await this.git.revparse('HEAD');
76
+ const filePath = path.resolve(LAST_GENERATION_FILE);
77
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
78
+ fs.writeFileSync(filePath, hash.trim());
79
+ }
80
+ catch {
81
+ // Non-critical, just skip
82
+ }
83
+ }
84
+ readLastGenerationHash() {
85
+ try {
86
+ const filePath = path.resolve(LAST_GENERATION_FILE);
87
+ if (fs.existsSync(filePath)) {
88
+ return fs.readFileSync(filePath, 'utf-8').trim();
89
+ }
90
+ }
91
+ catch {
92
+ // Ignore read errors
93
+ }
94
+ return null;
95
+ }
96
+ async isGitRepo() {
97
+ try {
98
+ return await this.git.checkIsRepo();
99
+ }
100
+ catch {
101
+ return false;
102
+ }
103
+ }
104
+ async isValidCommit(hash) {
105
+ try {
106
+ await this.git.catFile(['-t', hash]);
107
+ return true;
108
+ }
109
+ catch {
110
+ return false;
111
+ }
112
+ }
113
+ addFiles(set, diffOutput) {
114
+ const lines = diffOutput.trim().split('\n').filter(line => line.length > 0);
115
+ for (const line of lines) {
116
+ set.add(path.resolve(line));
117
+ }
118
+ }
119
+ }
@@ -36,7 +36,12 @@ export type ConversionConfiguration = {
36
36
  };
37
37
  export declare function pathToTsGlobPath(path: string): string;
38
38
  export declare function createTsMorphProject(): Project;
39
- export declare function convertAllEntities(config: ConversionConfiguration): EntityInfo[];
39
+ /**
40
+ * Converts all entities found in the given path configuration.
41
+ * @param config the conversion configuration
42
+ * @param changedFiles optional set of absolute file paths to limit processing to. If null, all files are processed.
43
+ */
44
+ export declare function convertAllEntities(config: ConversionConfiguration, changedFiles?: Set<string> | null): EntityInfo[];
40
45
  /**
41
46
  * Will return the relative path from the 'from' path to the 'to' path
42
47
  * @param from path to start from
@@ -199,7 +199,12 @@ export function createTsMorphProject() {
199
199
  // }
200
200
  });
201
201
  }
202
- export function convertAllEntities(config) {
202
+ /**
203
+ * Converts all entities found in the given path configuration.
204
+ * @param config the conversion configuration
205
+ * @param changedFiles optional set of absolute file paths to limit processing to. If null, all files are processed.
206
+ */
207
+ export function convertAllEntities(config, changedFiles) {
203
208
  const entities = [];
204
209
  const project = createTsMorphProject();
205
210
  if (config.verbose) {
@@ -215,6 +220,10 @@ export function convertAllEntities(config) {
215
220
  const absSourcePath = path.resolve(sourceFile.getFilePath());
216
221
  // make sure this file is in our configured paths and not just introduced by the ts-config
217
222
  if (absSourcePath.startsWith(absEntitiesPath)) {
223
+ // Skip files that haven't changed if incremental mode is active
224
+ if (changedFiles && !changedFiles.has(absSourcePath)) {
225
+ continue;
226
+ }
218
227
  const conversionContext = createConversionContext(new TypescriptConverterStrategy(new TypescriptConversionState(config.application), config.logger));
219
228
  const exportedDeclarations = sourceFile.getExportedDeclarations();
220
229
  exportedDeclarations.forEach((exportedDeclarationEntries, name) => {
@@ -1,5 +1,5 @@
1
1
  import { ITypeConverter } from './ITypeConverter.js';
2
- import { Logger } from '../Logger.js';
2
+ import { Logger } from '../../internal/Logger.js';
3
3
  /**
4
4
  * The {@link IConverterStrategy} is used to determine how to convert a specific language type to a Continuum IDL.
5
5
  * The {@link IConverterStrategy} should be reusable and thread safe.
@@ -1,6 +1,6 @@
1
1
  import { C3Type } from '@kinotic-ai/idl';
2
- import { ITypeConverter } from '../ITypeConverter.js';
3
- import { IConversionContext } from '../IConversionContext.js';
2
+ import { ITypeConverter } from '../../../internal/converter/ITypeConverter.js';
3
+ import { IConversionContext } from '../../../internal/converter/IConversionContext.js';
4
4
  import { StatementMapper } from './StatementMapper.js';
5
5
  import { StatementMapperConversionState } from './StatementMapperConversionState.js';
6
6
  export declare class ArrayC3TypeToStatementMapper implements ITypeConverter<C3Type, StatementMapper, StatementMapperConversionState> {
@@ -1,6 +1,6 @@
1
1
  import { C3Type } from '@kinotic-ai/idl';
2
- import { ITypeConverter } from '../ITypeConverter.js';
3
- import { IConversionContext } from '../IConversionContext.js';
2
+ import { ITypeConverter } from '../../../internal/converter/ITypeConverter.js';
3
+ import { IConversionContext } from '../../../internal/converter/IConversionContext.js';
4
4
  import { StatementMapper } from './StatementMapper.js';
5
5
  import { StatementMapperConversionState } from './StatementMapperConversionState.js';
6
6
  export declare class ObjectC3TypeToStatementMapper implements ITypeConverter<C3Type, StatementMapper, StatementMapperConversionState> {
@@ -1,6 +1,6 @@
1
1
  import { C3Type } from '@kinotic-ai/idl';
2
- import { IConversionContext } from '../IConversionContext.js';
3
- import { ITypeConverter } from '../ITypeConverter.js';
2
+ import { IConversionContext } from '../../../internal/converter/IConversionContext.js';
3
+ import { ITypeConverter } from '../../../internal/converter/ITypeConverter.js';
4
4
  import { StatementMapper } from './StatementMapper.js';
5
5
  import { StatementMapperConversionState } from './StatementMapperConversionState.js';
6
6
  export declare class PrimitiveC3TypeToStatementMapper implements ITypeConverter<C3Type, StatementMapper, StatementMapperConversionState> {
@@ -1,4 +1,4 @@
1
- import { getRelativeImportPath, tryGetNodeModuleName } from '../../Utils.js';
1
+ import { getRelativeImportPath, tryGetNodeModuleName } from '../../../internal/Utils.js';
2
2
  export class MultiStatementMapper {
3
3
  _state;
4
4
  _mappers;
@@ -1,4 +1,4 @@
1
- import { BaseConversionState } from '../common/BaseConversionState.js';
1
+ import { BaseConversionState } from '../../../internal/converter/common/BaseConversionState.js';
2
2
  export declare class StatementMapperConversionState extends BaseConversionState {
3
3
  sourceName: string;
4
4
  targetName: string;
@@ -1,4 +1,4 @@
1
- import { BaseConversionState } from '../common/BaseConversionState.js';
1
+ import { BaseConversionState } from '../../../internal/converter/common/BaseConversionState.js';
2
2
  export class StatementMapperConversionState extends BaseConversionState {
3
3
  sourceName = 'entity';
4
4
  targetName = 'ret';
@@ -1,7 +1,7 @@
1
1
  import { C3Type } from '@kinotic-ai/idl';
2
- import { Logger } from '../../Logger.js';
3
- import { IConverterStrategy } from '../IConverterStrategy.js';
4
- import { ITypeConverter } from '../ITypeConverter.js';
2
+ import { Logger } from '../../../internal/Logger.js';
3
+ import { IConverterStrategy } from '../../../internal/converter/IConverterStrategy.js';
4
+ import { ITypeConverter } from '../../../internal/converter/ITypeConverter.js';
5
5
  import { StatementMapper } from './StatementMapper.js';
6
6
  import { StatementMapperConversionState } from './StatementMapperConversionState.js';
7
7
  export declare class StatementMapperConverterStrategy implements IConverterStrategy<C3Type, StatementMapper, StatementMapperConversionState> {
@@ -1,6 +1,6 @@
1
1
  import { C3Type } from '@kinotic-ai/idl';
2
- import { ITypeConverter } from '../ITypeConverter.js';
3
- import { IConversionContext } from '../IConversionContext.js';
2
+ import { ITypeConverter } from '../../../internal/converter/ITypeConverter.js';
3
+ import { IConversionContext } from '../../../internal/converter/IConversionContext.js';
4
4
  import { StatementMapper } from './StatementMapper.js';
5
5
  import { StatementMapperConversionState } from './StatementMapperConversionState.js';
6
6
  export declare class UnionC3TypeToStatementMapper implements ITypeConverter<C3Type, StatementMapper, StatementMapperConversionState> {
@@ -1,5 +1,5 @@
1
1
  import { UnionC3Type } from '@kinotic-ai/idl';
2
- import { ConverterConstants } from '../ConverterConstants.js';
2
+ import { ConverterConstants } from '../../../internal/converter/ConverterConstants.js';
3
3
  import { MultiStatementMapper, LiteralStatementMapper } from './StatementMapper.js';
4
4
  import { camel } from 'radash';
5
5
  export class UnionC3TypeToStatementMapper {
@@ -1,8 +1,8 @@
1
1
  import { C3Type } from '@kinotic-ai/idl';
2
2
  import { Type } from 'ts-morph';
3
3
  import { TypescriptConversionState } from './TypescriptConversionState.js';
4
- import { IConversionContext } from '../IConversionContext.js';
5
- import { ITypeConverter } from '../ITypeConverter.js';
4
+ import { IConversionContext } from '../../../internal/converter/IConversionContext.js';
5
+ import { ITypeConverter } from '../../../internal/converter/ITypeConverter.js';
6
6
  export declare class ArrayToC3Type implements ITypeConverter<Type, C3Type, TypescriptConversionState> {
7
7
  convert(value: Type, conversionContext: IConversionContext<Type, C3Type, TypescriptConversionState>): C3Type;
8
8
  supports(value: Type, conversionState: TypescriptConversionState): boolean;
@@ -1,8 +1,8 @@
1
1
  import { Type } from 'ts-morph';
2
2
  import { C3Type } from '@kinotic-ai/idl';
3
3
  import { TypescriptConversionState } from './TypescriptConversionState.js';
4
- import { IConversionContext } from '../IConversionContext.js';
5
- import { ITypeConverter } from '../ITypeConverter.js';
4
+ import { IConversionContext } from '../../../internal/converter/IConversionContext.js';
5
+ import { ITypeConverter } from '../../../internal/converter/ITypeConverter.js';
6
6
  /**
7
7
  * Converts a typescript enum to a C3 Enum
8
8
  */
@@ -1,8 +1,8 @@
1
1
  import { Type } from 'ts-morph';
2
2
  import { C3Type } from '@kinotic-ai/idl';
3
3
  import { TypescriptConversionState } from './TypescriptConversionState.js';
4
- import { IConversionContext } from '../IConversionContext.js';
5
- import { ITypeConverter } from '../ITypeConverter.js';
4
+ import { IConversionContext } from '../../../internal/converter/IConversionContext.js';
5
+ import { ITypeConverter } from '../../../internal/converter/ITypeConverter.js';
6
6
  /**
7
7
  * Converts a typescript Class, Interface, or Type to a C3Type
8
8
  */
@@ -1,5 +1,5 @@
1
1
  import { ObjectC3Type, PropertyDefinition } from '@kinotic-ai/idl';
2
- import { ConverterConstants } from '../ConverterConstants.js';
2
+ import { ConverterConstants } from '../../../internal/converter/ConverterConstants.js';
3
3
  import { tsDecoratorToC3Decorator, convertPrecisionToC3Type } from './ConverterUtils.js';
4
4
  import { TenantIdDecorator } from '@kinotic-ai/os-api';
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { SpecificTypesConverter } from '../SpecificTypesConverter.js';
1
+ import { SpecificTypesConverter } from '../../../internal/converter/SpecificTypesConverter.js';
2
2
  import { Type } from 'ts-morph';
3
3
  import { TypescriptConversionState } from './TypescriptConversionState.js';
4
4
  import { C3Type } from '@kinotic-ai/idl';
@@ -1,4 +1,4 @@
1
- import { SpecificTypesConverter } from '../SpecificTypesConverter.js';
1
+ import { SpecificTypesConverter } from '../../../internal/converter/SpecificTypesConverter.js';
2
2
  import { BooleanC3Type, StringC3Type, IntC3Type, DateC3Type, VoidC3Type } from '@kinotic-ai/idl';
3
3
  /**
4
4
  * Converts typescript primitive types to C3Types
@@ -1,8 +1,8 @@
1
1
  import { C3Type } from '@kinotic-ai/idl';
2
2
  import { ts, Type } from 'ts-morph';
3
- import { ITypeConverter } from '../ITypeConverter.js';
3
+ import { ITypeConverter } from '../../../internal/converter/ITypeConverter.js';
4
4
  import { TypescriptConversionState } from './TypescriptConversionState.js';
5
- import { IConversionContext } from '../IConversionContext.js';
5
+ import { IConversionContext } from '../../../internal/converter/IConversionContext.js';
6
6
  export declare class QueryOptionsToC3Type implements ITypeConverter<Type, C3Type, TypescriptConversionState> {
7
7
  convert(value: Type<ts.Type>, conversionContext: IConversionContext<Type, C3Type, TypescriptConversionState>): C3Type;
8
8
  supports(value: Type<ts.Type>, conversionState: TypescriptConversionState): boolean;
@@ -1,8 +1,8 @@
1
1
  import { C3Type } from '@kinotic-ai/idl';
2
2
  import { ts, Type } from 'ts-morph';
3
- import { ITypeConverter } from '../ITypeConverter.js';
3
+ import { ITypeConverter } from '../../../internal/converter/ITypeConverter.js';
4
4
  import { TypescriptConversionState } from './TypescriptConversionState.js';
5
- import { IConversionContext } from '../IConversionContext.js';
5
+ import { IConversionContext } from '../../../internal/converter/IConversionContext.js';
6
6
  export declare class TenantSelectionToC3Type implements ITypeConverter<Type, C3Type, TypescriptConversionState> {
7
7
  convert(value: Type<ts.Type>, conversionContext: IConversionContext<Type, C3Type, TypescriptConversionState>): C3Type;
8
8
  supports(value: Type<ts.Type>, conversionState: TypescriptConversionState): boolean;
@@ -1,4 +1,4 @@
1
- import { BaseConversionState } from '../common/BaseConversionState.js';
1
+ import { BaseConversionState } from '../../../internal/converter/common/BaseConversionState.js';
2
2
  /**
3
3
  * The state of the Typescript to C3Type conversion process.
4
4
  */
@@ -1,4 +1,4 @@
1
- import { BaseConversionState } from '../common/BaseConversionState.js';
1
+ import { BaseConversionState } from '../../../internal/converter/common/BaseConversionState.js';
2
2
  /**
3
3
  * The state of the Typescript to C3Type conversion process.
4
4
  */
@@ -1,9 +1,9 @@
1
1
  import { C3Type } from '@kinotic-ai/idl';
2
2
  import { Type } from 'ts-morph';
3
- import { IConverterStrategy } from '../IConverterStrategy.js';
4
- import { Logger } from '../../Logger.js';
3
+ import { IConverterStrategy } from '../../../internal/converter/IConverterStrategy.js';
4
+ import { Logger } from '../../../internal/Logger.js';
5
5
  import { TypescriptConversionState } from './TypescriptConversionState.js';
6
- import { ITypeConverter } from '../ITypeConverter.js';
6
+ import { ITypeConverter } from '../../../internal/converter/ITypeConverter.js';
7
7
  export declare class TypescriptConverterStrategy implements IConverterStrategy<Type, C3Type, TypescriptConversionState> {
8
8
  private readonly _initialState;
9
9
  private readonly _logger;
@@ -1,8 +1,8 @@
1
1
  import { C3Type } from '@kinotic-ai/idl';
2
2
  import { Type } from 'ts-morph';
3
3
  import { TypescriptConversionState } from './TypescriptConversionState.js';
4
- import { ITypeConverter } from '../ITypeConverter.js';
5
- import { IConversionContext } from '../IConversionContext.js';
4
+ import { ITypeConverter } from '../../../internal/converter/ITypeConverter.js';
5
+ import { IConversionContext } from '../../../internal/converter/IConversionContext.js';
6
6
  /**
7
7
  * Converts a typescript union type to a C3Type
8
8
  */
@@ -0,0 +1,31 @@
1
+ import { z } from 'zod';
2
+ export declare const PropertySchemaSchema: z.ZodObject<{
3
+ type: z.ZodOptional<z.ZodEnum<{
4
+ string: "string";
5
+ number: "number";
6
+ boolean: "boolean";
7
+ integer: "integer";
8
+ }>>;
9
+ description: z.ZodOptional<z.ZodString>;
10
+ default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
11
+ enum: z.ZodOptional<z.ZodArray<z.ZodString>>;
12
+ }, z.core.$strip>;
13
+ export declare const SpawnConfigSchema: z.ZodObject<{
14
+ inherits: z.ZodOptional<z.ZodString>;
15
+ globals: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
16
+ propertySchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
17
+ type: z.ZodOptional<z.ZodEnum<{
18
+ string: "string";
19
+ number: "number";
20
+ boolean: "boolean";
21
+ integer: "integer";
22
+ }>>;
23
+ description: z.ZodOptional<z.ZodString>;
24
+ default: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
25
+ enum: z.ZodOptional<z.ZodArray<z.ZodString>>;
26
+ }, z.core.$strip>>>;
27
+ }, z.core.$strip>;
28
+ export type PropertySchema = z.infer<typeof PropertySchemaSchema>;
29
+ export type SpawnConfig = z.infer<typeof SpawnConfigSchema>;
30
+ export type GlobalsType = Record<string, unknown>;
31
+ export type PropertySchemaType = Record<string, PropertySchema>;
@@ -0,0 +1,12 @@
1
+ import { z } from 'zod';
2
+ export const PropertySchemaSchema = z.object({
3
+ type: z.enum(['string', 'number', 'integer', 'boolean']).optional(),
4
+ description: z.string().optional(),
5
+ default: z.union([z.string(), z.number(), z.boolean()]).optional(),
6
+ enum: z.array(z.string()).optional(),
7
+ });
8
+ export const SpawnConfigSchema = z.object({
9
+ inherits: z.string().optional(),
10
+ globals: z.record(z.string(), z.unknown()).optional(),
11
+ propertySchema: z.record(z.string(), PropertySchemaSchema).optional(),
12
+ });
@@ -0,0 +1,27 @@
1
+ import { SpawnResolver } from './SpawnResolver.js';
2
+ export default class SpawnEngine {
3
+ private engine;
4
+ private spawnResolver;
5
+ constructor(resolver: SpawnResolver);
6
+ /**
7
+ * Renders the specified Spawn
8
+ * A Spawn is a directory that contains templates, an optional spawn.json file, and template parameters in folder and filenames
9
+ *
10
+ * This is done by performing the following
11
+ *
12
+ * - Will recursively walk the spawn copying any files or directories encountered
13
+ * -- If a template file is encountered, it will be parsed and rendered prior to copying
14
+ *
15
+ * @param spawn the name of the spawn to parse and render. This is the name of the directory containing the spawn.json
16
+ * @param destination the target directory where rendered data will be sent
17
+ * @param context the values to be provided to the templates while rendering
18
+ * @return a promise containing all the original values plus any added during rendering
19
+ */
20
+ renderSpawn(spawn: string, destination: string, context?: Record<string, unknown>): Promise<Record<string, unknown> | undefined>;
21
+ private promptForMissingProperties;
22
+ private _renderFile;
23
+ private _renderDirectory;
24
+ private logDebug;
25
+ private shouldIgnore;
26
+ }
27
+ export declare const spawnEngine: SpawnEngine;