tlc-claude-code 1.2.28 → 1.3.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 +9 -4
- package/dashboard/dist/components/UsagePane.d.ts +13 -0
- package/dashboard/dist/components/UsagePane.js +51 -0
- package/dashboard/dist/components/UsagePane.test.d.ts +1 -0
- package/dashboard/dist/components/UsagePane.test.js +142 -0
- package/dashboard/dist/components/WorkspaceDocsPane.d.ts +19 -0
- package/dashboard/dist/components/WorkspaceDocsPane.js +146 -0
- package/dashboard/dist/components/WorkspaceDocsPane.test.d.ts +1 -0
- package/dashboard/dist/components/WorkspaceDocsPane.test.js +242 -0
- package/dashboard/dist/components/WorkspacePane.d.ts +18 -0
- package/dashboard/dist/components/WorkspacePane.js +17 -0
- package/dashboard/dist/components/WorkspacePane.test.d.ts +1 -0
- package/dashboard/dist/components/WorkspacePane.test.js +84 -0
- package/package.json +15 -4
- package/scripts/capture-screenshots.js +170 -0
- package/scripts/docs-update.js +253 -0
- package/scripts/generate-screenshots.js +321 -0
- package/scripts/project-docs.js +377 -0
- package/scripts/vps-setup.sh +477 -0
- package/server/lib/architecture-command.js +450 -0
- package/server/lib/architecture-command.test.js +754 -0
- package/server/lib/ast-analyzer.js +324 -0
- package/server/lib/ast-analyzer.test.js +437 -0
- package/server/lib/auth-system.test.js +4 -1
- package/server/lib/boundary-detector.js +427 -0
- package/server/lib/boundary-detector.test.js +320 -0
- package/server/lib/budget-alerts.js +138 -0
- package/server/lib/budget-alerts.test.js +235 -0
- package/server/lib/candidates-tracker.js +210 -0
- package/server/lib/candidates-tracker.test.js +300 -0
- package/server/lib/checkpoint-manager.js +251 -0
- package/server/lib/checkpoint-manager.test.js +474 -0
- package/server/lib/circular-detector.js +337 -0
- package/server/lib/circular-detector.test.js +353 -0
- package/server/lib/cohesion-analyzer.js +310 -0
- package/server/lib/cohesion-analyzer.test.js +447 -0
- package/server/lib/contract-testing.js +625 -0
- package/server/lib/contract-testing.test.js +342 -0
- package/server/lib/conversion-planner.js +469 -0
- package/server/lib/conversion-planner.test.js +361 -0
- package/server/lib/convert-command.js +351 -0
- package/server/lib/convert-command.test.js +608 -0
- package/server/lib/coupling-calculator.js +189 -0
- package/server/lib/coupling-calculator.test.js +509 -0
- package/server/lib/dependency-graph.js +367 -0
- package/server/lib/dependency-graph.test.js +516 -0
- package/server/lib/duplication-detector.js +349 -0
- package/server/lib/duplication-detector.test.js +401 -0
- package/server/lib/example-service.js +616 -0
- package/server/lib/example-service.test.js +397 -0
- package/server/lib/impact-scorer.js +184 -0
- package/server/lib/impact-scorer.test.js +211 -0
- package/server/lib/mermaid-generator.js +358 -0
- package/server/lib/mermaid-generator.test.js +301 -0
- package/server/lib/messaging-patterns.js +750 -0
- package/server/lib/messaging-patterns.test.js +213 -0
- package/server/lib/microservice-template.js +386 -0
- package/server/lib/microservice-template.test.js +325 -0
- package/server/lib/new-project-microservice.js +450 -0
- package/server/lib/new-project-microservice.test.js +600 -0
- package/server/lib/refactor-command.js +326 -0
- package/server/lib/refactor-command.test.js +528 -0
- package/server/lib/refactor-executor.js +254 -0
- package/server/lib/refactor-executor.test.js +305 -0
- package/server/lib/refactor-observer.js +292 -0
- package/server/lib/refactor-observer.test.js +422 -0
- package/server/lib/refactor-progress.js +193 -0
- package/server/lib/refactor-progress.test.js +251 -0
- package/server/lib/refactor-reporter.js +237 -0
- package/server/lib/refactor-reporter.test.js +247 -0
- package/server/lib/semantic-analyzer.js +198 -0
- package/server/lib/semantic-analyzer.test.js +474 -0
- package/server/lib/service-scaffold.js +486 -0
- package/server/lib/service-scaffold.test.js +373 -0
- package/server/lib/shared-kernel.js +578 -0
- package/server/lib/shared-kernel.test.js +255 -0
- package/server/lib/traefik-config.js +282 -0
- package/server/lib/traefik-config.test.js +312 -0
- package/server/lib/usage-command.js +218 -0
- package/server/lib/usage-command.test.js +391 -0
- package/server/lib/usage-formatter.js +192 -0
- package/server/lib/usage-formatter.test.js +267 -0
- package/server/lib/usage-history.js +122 -0
- package/server/lib/usage-history.test.js +206 -0
- package/server/package-lock.json +14 -0
- package/server/package.json +1 -0
- package/templates/docs-sync.yml +91 -0
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Kernel Generator Module
|
|
3
|
+
* Generates shared code structure for microservices
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Capitalize first letter of string
|
|
8
|
+
* @param {string} str - String to capitalize
|
|
9
|
+
* @returns {string} Capitalized string
|
|
10
|
+
*/
|
|
11
|
+
function capitalize(str) {
|
|
12
|
+
if (!str) return '';
|
|
13
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Generate package.json for shared kernel
|
|
18
|
+
* @param {Object} config - Configuration
|
|
19
|
+
* @param {string} config.projectName - Project name
|
|
20
|
+
* @returns {Object} Package.json content
|
|
21
|
+
*/
|
|
22
|
+
function generatePackageJson(config) {
|
|
23
|
+
const { projectName = 'app' } = config;
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
name: `@${projectName}/shared`,
|
|
27
|
+
version: '1.0.0',
|
|
28
|
+
description: `Shared types, contracts, and utilities for ${projectName}`,
|
|
29
|
+
type: 'module',
|
|
30
|
+
main: './index.js',
|
|
31
|
+
types: './index.d.ts',
|
|
32
|
+
exports: {
|
|
33
|
+
'.': {
|
|
34
|
+
types: './index.d.ts',
|
|
35
|
+
import: './index.js',
|
|
36
|
+
},
|
|
37
|
+
'./types': {
|
|
38
|
+
types: './types/index.d.ts',
|
|
39
|
+
import: './types/index.js',
|
|
40
|
+
},
|
|
41
|
+
'./contracts': {
|
|
42
|
+
types: './contracts/index.d.ts',
|
|
43
|
+
import: './contracts/index.js',
|
|
44
|
+
},
|
|
45
|
+
'./events': {
|
|
46
|
+
types: './events/index.d.ts',
|
|
47
|
+
import: './events/index.js',
|
|
48
|
+
},
|
|
49
|
+
'./utils': {
|
|
50
|
+
types: './utils/index.d.ts',
|
|
51
|
+
import: './utils/index.js',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
scripts: {
|
|
55
|
+
build: 'tsc',
|
|
56
|
+
clean: 'rm -rf dist',
|
|
57
|
+
},
|
|
58
|
+
devDependencies: {
|
|
59
|
+
typescript: '^5.0.0',
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Generate TypeScript types for shared kernel
|
|
66
|
+
* @param {Object} config - Configuration
|
|
67
|
+
* @param {Array<string>} config.services - Service names
|
|
68
|
+
* @returns {string} TypeScript type definitions
|
|
69
|
+
*/
|
|
70
|
+
function generateTypes(config) {
|
|
71
|
+
const { services = [] } = config;
|
|
72
|
+
|
|
73
|
+
const lines = [];
|
|
74
|
+
|
|
75
|
+
// Common types
|
|
76
|
+
lines.push('// Common Types');
|
|
77
|
+
lines.push('');
|
|
78
|
+
lines.push('export type ID = string;');
|
|
79
|
+
lines.push('');
|
|
80
|
+
lines.push('export type Timestamp = string;');
|
|
81
|
+
lines.push('');
|
|
82
|
+
lines.push('export interface PaginatedResponse<T> {');
|
|
83
|
+
lines.push(' data: T[];');
|
|
84
|
+
lines.push(' total: number;');
|
|
85
|
+
lines.push(' page: number;');
|
|
86
|
+
lines.push(' pageSize: number;');
|
|
87
|
+
lines.push(' hasMore: boolean;');
|
|
88
|
+
lines.push('}');
|
|
89
|
+
lines.push('');
|
|
90
|
+
|
|
91
|
+
// Service-specific types
|
|
92
|
+
if (services.length > 0) {
|
|
93
|
+
lines.push('// Service-Specific Types');
|
|
94
|
+
lines.push('');
|
|
95
|
+
|
|
96
|
+
for (const service of services) {
|
|
97
|
+
const typeName = capitalize(service);
|
|
98
|
+
lines.push(`export interface ${typeName} {`);
|
|
99
|
+
lines.push(' id: ID;');
|
|
100
|
+
lines.push(' createdAt: Timestamp;');
|
|
101
|
+
lines.push(' updatedAt: Timestamp;');
|
|
102
|
+
lines.push('}');
|
|
103
|
+
lines.push('');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return lines.join('\n');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Generate JSON Schema contracts for services
|
|
112
|
+
* @param {Array<string>} services - Service names
|
|
113
|
+
* @returns {Object} Contract schemas by service
|
|
114
|
+
*/
|
|
115
|
+
function generateContracts(services) {
|
|
116
|
+
const contracts = {};
|
|
117
|
+
|
|
118
|
+
for (const service of services) {
|
|
119
|
+
const serviceName = capitalize(service);
|
|
120
|
+
|
|
121
|
+
contracts[service] = {
|
|
122
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
123
|
+
$id: `${service}-contract`,
|
|
124
|
+
title: `${serviceName} Service Contract`,
|
|
125
|
+
description: `API contract for ${serviceName} service`,
|
|
126
|
+
definitions: {
|
|
127
|
+
Request: {
|
|
128
|
+
type: 'object',
|
|
129
|
+
properties: {
|
|
130
|
+
id: { type: 'string', description: 'Resource identifier' },
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
Response: {
|
|
134
|
+
type: 'object',
|
|
135
|
+
properties: {
|
|
136
|
+
id: { type: 'string' },
|
|
137
|
+
createdAt: { type: 'string', format: 'date-time' },
|
|
138
|
+
updatedAt: { type: 'string', format: 'date-time' },
|
|
139
|
+
},
|
|
140
|
+
required: ['id'],
|
|
141
|
+
},
|
|
142
|
+
ErrorResponse: {
|
|
143
|
+
type: 'object',
|
|
144
|
+
properties: {
|
|
145
|
+
error: {
|
|
146
|
+
type: 'object',
|
|
147
|
+
properties: {
|
|
148
|
+
code: { type: 'string' },
|
|
149
|
+
message: { type: 'string' },
|
|
150
|
+
details: { type: 'object' },
|
|
151
|
+
},
|
|
152
|
+
required: ['code', 'message'],
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
required: ['error'],
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return contracts;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Generate event definitions for shared kernel
|
|
166
|
+
* @param {Array<string>} events - Event names
|
|
167
|
+
* @returns {Object} Event definitions
|
|
168
|
+
*/
|
|
169
|
+
function generateEvents(events) {
|
|
170
|
+
// Base event interface
|
|
171
|
+
const base = `// Base Event Interface
|
|
172
|
+
export interface BaseEvent<T = unknown> {
|
|
173
|
+
id: string;
|
|
174
|
+
timestamp: string;
|
|
175
|
+
source: string;
|
|
176
|
+
type: string;
|
|
177
|
+
payload: T;
|
|
178
|
+
metadata?: Record<string, unknown>;
|
|
179
|
+
}
|
|
180
|
+
`;
|
|
181
|
+
|
|
182
|
+
// Per-event schemas
|
|
183
|
+
const schemas = {};
|
|
184
|
+
for (const event of events) {
|
|
185
|
+
schemas[event] = `export interface ${event}Event extends BaseEvent<${event}Payload> {
|
|
186
|
+
type: '${event}';
|
|
187
|
+
payload: ${event}Payload;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export interface ${event}Payload {
|
|
191
|
+
// Define payload fields for ${event}
|
|
192
|
+
}
|
|
193
|
+
`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Event catalog
|
|
197
|
+
const catalogLines = [
|
|
198
|
+
'// Event Catalog',
|
|
199
|
+
'',
|
|
200
|
+
'export const EventCatalog = {',
|
|
201
|
+
];
|
|
202
|
+
|
|
203
|
+
for (const event of events) {
|
|
204
|
+
catalogLines.push(` ${event}: '${event}',`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
catalogLines.push('} as const;');
|
|
208
|
+
catalogLines.push('');
|
|
209
|
+
catalogLines.push('export type EventType = keyof typeof EventCatalog;');
|
|
210
|
+
|
|
211
|
+
const catalog = catalogLines.join('\n');
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
base,
|
|
215
|
+
schemas,
|
|
216
|
+
catalog,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Generate utility modules for shared kernel
|
|
222
|
+
* @returns {Object} Utility module contents
|
|
223
|
+
*/
|
|
224
|
+
function generateUtils() {
|
|
225
|
+
const logger = `// Logger Utility
|
|
226
|
+
|
|
227
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
228
|
+
|
|
229
|
+
export interface Logger {
|
|
230
|
+
debug(message: string, meta?: Record<string, unknown>): void;
|
|
231
|
+
info(message: string, meta?: Record<string, unknown>): void;
|
|
232
|
+
warn(message: string, meta?: Record<string, unknown>): void;
|
|
233
|
+
error(message: string, meta?: Record<string, unknown>): void;
|
|
234
|
+
log(level: LogLevel, message: string, meta?: Record<string, unknown>): void;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export function createLogger(name: string): Logger {
|
|
238
|
+
const log = (level: LogLevel, message: string, meta?: Record<string, unknown>) => {
|
|
239
|
+
const timestamp = new Date().toISOString();
|
|
240
|
+
console[level](\`[\${timestamp}] [\${level.toUpperCase()}] [\${name}] \${message}\`, meta || '');
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
debug: (message, meta) => log('debug', message, meta),
|
|
245
|
+
info: (message, meta) => log('info', message, meta),
|
|
246
|
+
warn: (message, meta) => log('warn', message, meta),
|
|
247
|
+
error: (message, meta) => log('error', message, meta),
|
|
248
|
+
log,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
`;
|
|
252
|
+
|
|
253
|
+
const errors = `// Error Classes
|
|
254
|
+
|
|
255
|
+
export class AppError extends Error {
|
|
256
|
+
public readonly code: string;
|
|
257
|
+
public readonly statusCode: number;
|
|
258
|
+
public readonly details?: Record<string, unknown>;
|
|
259
|
+
|
|
260
|
+
constructor(message: string, code: string = 'APP_ERROR', statusCode: number = 500, details?: Record<string, unknown>) {
|
|
261
|
+
super(message);
|
|
262
|
+
this.name = this.constructor.name;
|
|
263
|
+
this.code = code;
|
|
264
|
+
this.statusCode = statusCode;
|
|
265
|
+
this.details = details;
|
|
266
|
+
Error.captureStackTrace(this, this.constructor);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
toJSON() {
|
|
270
|
+
return {
|
|
271
|
+
error: {
|
|
272
|
+
code: this.code,
|
|
273
|
+
message: this.message,
|
|
274
|
+
details: this.details,
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export class ValidationError extends AppError {
|
|
281
|
+
constructor(message: string, details?: Record<string, unknown>) {
|
|
282
|
+
super(message, 'VALIDATION_ERROR', 400, details);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export class NotFoundError extends AppError {
|
|
287
|
+
constructor(resource: string, id?: string) {
|
|
288
|
+
const message = id ? \`\${resource} with id '\${id}' not found\` : \`\${resource} not found\`;
|
|
289
|
+
super(message, 'NOT_FOUND', 404, { resource, id });
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export class UnauthorizedError extends AppError {
|
|
294
|
+
constructor(message: string = 'Unauthorized') {
|
|
295
|
+
super(message, 'UNAUTHORIZED', 401);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export class ForbiddenError extends AppError {
|
|
300
|
+
constructor(message: string = 'Forbidden') {
|
|
301
|
+
super(message, 'FORBIDDEN', 403);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
`;
|
|
305
|
+
|
|
306
|
+
const validation = `// Validation Helpers
|
|
307
|
+
|
|
308
|
+
export interface ValidationResult {
|
|
309
|
+
valid: boolean;
|
|
310
|
+
errors: ValidationError[];
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export interface ValidationError {
|
|
314
|
+
field: string;
|
|
315
|
+
message: string;
|
|
316
|
+
code: string;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export function validate<T>(
|
|
320
|
+
data: T,
|
|
321
|
+
rules: Record<keyof T, (value: unknown) => string | null>
|
|
322
|
+
): ValidationResult {
|
|
323
|
+
const errors: ValidationError[] = [];
|
|
324
|
+
|
|
325
|
+
for (const [field, rule] of Object.entries(rules) as Array<[keyof T, (value: unknown) => string | null]>) {
|
|
326
|
+
const error = rule(data[field]);
|
|
327
|
+
if (error) {
|
|
328
|
+
errors.push({
|
|
329
|
+
field: String(field),
|
|
330
|
+
message: error,
|
|
331
|
+
code: 'VALIDATION_FAILED',
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return {
|
|
337
|
+
valid: errors.length === 0,
|
|
338
|
+
errors,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export const validators = {
|
|
343
|
+
required: (value: unknown) => (value == null || value === '' ? 'Required' : null),
|
|
344
|
+
email: (value: unknown) =>
|
|
345
|
+
typeof value === 'string' && /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value) ? null : 'Invalid email',
|
|
346
|
+
minLength: (min: number) => (value: unknown) =>
|
|
347
|
+
typeof value === 'string' && value.length >= min ? null : \`Minimum length is \${min}\`,
|
|
348
|
+
maxLength: (max: number) => (value: unknown) =>
|
|
349
|
+
typeof value === 'string' && value.length <= max ? null : \`Maximum length is \${max}\`,
|
|
350
|
+
uuid: (value: unknown) =>
|
|
351
|
+
typeof value === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)
|
|
352
|
+
? null
|
|
353
|
+
: 'Invalid UUID',
|
|
354
|
+
};
|
|
355
|
+
`;
|
|
356
|
+
|
|
357
|
+
return {
|
|
358
|
+
logger,
|
|
359
|
+
errors,
|
|
360
|
+
validation,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Shared Kernel class for generating microservice shared code
|
|
366
|
+
*/
|
|
367
|
+
class SharedKernel {
|
|
368
|
+
/**
|
|
369
|
+
* Create a SharedKernel instance
|
|
370
|
+
* @param {Object} options - Configuration options
|
|
371
|
+
* @param {string} options.projectName - Project name
|
|
372
|
+
*/
|
|
373
|
+
constructor(options = {}) {
|
|
374
|
+
this.projectName = options.projectName || 'app';
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Generate complete shared kernel
|
|
379
|
+
* @param {Object} config - Generation config
|
|
380
|
+
* @param {Array<string>} config.services - Service names
|
|
381
|
+
* @param {Array<string>} config.events - Event names
|
|
382
|
+
* @returns {Object} Generated structure
|
|
383
|
+
*/
|
|
384
|
+
generate(config) {
|
|
385
|
+
const { services = [], events = [] } = config;
|
|
386
|
+
|
|
387
|
+
const directories = [
|
|
388
|
+
'shared',
|
|
389
|
+
'shared/types',
|
|
390
|
+
'shared/contracts',
|
|
391
|
+
'shared/events',
|
|
392
|
+
'shared/utils',
|
|
393
|
+
];
|
|
394
|
+
|
|
395
|
+
const files = [];
|
|
396
|
+
|
|
397
|
+
// Package.json
|
|
398
|
+
const pkg = generatePackageJson({ projectName: this.projectName });
|
|
399
|
+
files.push({
|
|
400
|
+
path: 'shared/package.json',
|
|
401
|
+
content: JSON.stringify(pkg, null, 2),
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
// Types
|
|
405
|
+
const types = generateTypes({ services });
|
|
406
|
+
files.push({
|
|
407
|
+
path: 'shared/types/index.ts',
|
|
408
|
+
content: types,
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
// Contracts
|
|
412
|
+
const contracts = generateContracts(services);
|
|
413
|
+
files.push({
|
|
414
|
+
path: 'shared/contracts/index.ts',
|
|
415
|
+
content: this._generateContractsIndex(contracts),
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
for (const [service, schema] of Object.entries(contracts)) {
|
|
419
|
+
files.push({
|
|
420
|
+
path: `shared/contracts/${service}.schema.json`,
|
|
421
|
+
content: JSON.stringify(schema, null, 2),
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Events
|
|
426
|
+
const eventDefs = generateEvents(events);
|
|
427
|
+
files.push({
|
|
428
|
+
path: 'shared/events/index.ts',
|
|
429
|
+
content: this._generateEventsIndex(eventDefs, events),
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
// Utils
|
|
433
|
+
const utils = generateUtils();
|
|
434
|
+
files.push({
|
|
435
|
+
path: 'shared/utils/logger.ts',
|
|
436
|
+
content: utils.logger,
|
|
437
|
+
});
|
|
438
|
+
files.push({
|
|
439
|
+
path: 'shared/utils/errors.ts',
|
|
440
|
+
content: utils.errors,
|
|
441
|
+
});
|
|
442
|
+
files.push({
|
|
443
|
+
path: 'shared/utils/validation.ts',
|
|
444
|
+
content: utils.validation,
|
|
445
|
+
});
|
|
446
|
+
files.push({
|
|
447
|
+
path: 'shared/utils/index.ts',
|
|
448
|
+
content: this._generateUtilsIndex(),
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// Root index
|
|
452
|
+
files.push({
|
|
453
|
+
path: 'shared/index.ts',
|
|
454
|
+
content: this._generateRootIndex(),
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
// tsconfig
|
|
458
|
+
files.push({
|
|
459
|
+
path: 'shared/tsconfig.json',
|
|
460
|
+
content: JSON.stringify(this._generateTsConfig(), null, 2),
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
return { directories, files };
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Generate contracts index file
|
|
468
|
+
* @private
|
|
469
|
+
*/
|
|
470
|
+
_generateContractsIndex(contracts) {
|
|
471
|
+
const lines = ['// Contract schemas'];
|
|
472
|
+
lines.push('');
|
|
473
|
+
|
|
474
|
+
for (const service of Object.keys(contracts)) {
|
|
475
|
+
lines.push(`export { default as ${capitalize(service)}Contract } from './${service}.schema.json';`);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
if (Object.keys(contracts).length === 0) {
|
|
479
|
+
lines.push('// No contracts defined');
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
return lines.join('\n') + '\n';
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Generate events index file
|
|
487
|
+
* @private
|
|
488
|
+
*/
|
|
489
|
+
_generateEventsIndex(eventDefs, events) {
|
|
490
|
+
const lines = [];
|
|
491
|
+
lines.push(eventDefs.base);
|
|
492
|
+
lines.push('');
|
|
493
|
+
|
|
494
|
+
for (const event of events) {
|
|
495
|
+
lines.push(eventDefs.schemas[event]);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
lines.push(eventDefs.catalog);
|
|
499
|
+
|
|
500
|
+
return lines.join('\n');
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Generate utils index file
|
|
505
|
+
* @private
|
|
506
|
+
*/
|
|
507
|
+
_generateUtilsIndex() {
|
|
508
|
+
return `export * from './logger';
|
|
509
|
+
export * from './errors';
|
|
510
|
+
export * from './validation';
|
|
511
|
+
`;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Generate root index file
|
|
516
|
+
* @private
|
|
517
|
+
*/
|
|
518
|
+
_generateRootIndex() {
|
|
519
|
+
return `export * from './types';
|
|
520
|
+
export * from './events';
|
|
521
|
+
export * from './utils';
|
|
522
|
+
`;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Generate TypeScript config
|
|
527
|
+
* @private
|
|
528
|
+
*/
|
|
529
|
+
_generateTsConfig() {
|
|
530
|
+
return {
|
|
531
|
+
compilerOptions: {
|
|
532
|
+
target: 'ES2020',
|
|
533
|
+
module: 'ESNext',
|
|
534
|
+
moduleResolution: 'node',
|
|
535
|
+
declaration: true,
|
|
536
|
+
declarationMap: true,
|
|
537
|
+
sourceMap: true,
|
|
538
|
+
outDir: './dist',
|
|
539
|
+
rootDir: './',
|
|
540
|
+
strict: true,
|
|
541
|
+
esModuleInterop: true,
|
|
542
|
+
skipLibCheck: true,
|
|
543
|
+
forceConsistentCasingInFileNames: true,
|
|
544
|
+
resolveJsonModule: true,
|
|
545
|
+
},
|
|
546
|
+
include: ['./**/*.ts'],
|
|
547
|
+
exclude: ['node_modules', 'dist'],
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Create shared kernel generator instance
|
|
554
|
+
* @param {Object} options - Generator options
|
|
555
|
+
* @returns {Object} Generator instance
|
|
556
|
+
*/
|
|
557
|
+
function createSharedKernel(options = {}) {
|
|
558
|
+
const kernel = new SharedKernel(options);
|
|
559
|
+
return {
|
|
560
|
+
generate: (config) => kernel.generate(config),
|
|
561
|
+
generatePackageJson: () => generatePackageJson({ projectName: kernel.projectName }),
|
|
562
|
+
generateTypes: (config) => generateTypes(config),
|
|
563
|
+
generateContracts: (services) => generateContracts(services),
|
|
564
|
+
generateEvents: (events) => generateEvents(events),
|
|
565
|
+
generateUtils: () => generateUtils(),
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
module.exports = {
|
|
570
|
+
SharedKernel,
|
|
571
|
+
createSharedKernel,
|
|
572
|
+
generatePackageJson,
|
|
573
|
+
generateTypes,
|
|
574
|
+
generateContracts,
|
|
575
|
+
generateEvents,
|
|
576
|
+
generateUtils,
|
|
577
|
+
capitalize,
|
|
578
|
+
};
|