newo 3.4.0 → 3.4.2

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 (79) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/api.d.ts +3 -1
  3. package/dist/api.js +49 -1
  4. package/dist/application/migration/MigrationEngine.d.ts +141 -0
  5. package/dist/application/migration/MigrationEngine.js +322 -0
  6. package/dist/application/migration/index.d.ts +5 -0
  7. package/dist/application/migration/index.js +5 -0
  8. package/dist/application/sync/SyncEngine.d.ts +134 -0
  9. package/dist/application/sync/SyncEngine.js +335 -0
  10. package/dist/application/sync/index.d.ts +5 -0
  11. package/dist/application/sync/index.js +5 -0
  12. package/dist/cli/commands/create-attribute.js +1 -1
  13. package/dist/cli/commands/create-customer.d.ts +3 -0
  14. package/dist/cli/commands/create-customer.js +159 -0
  15. package/dist/cli/commands/diff.d.ts +6 -0
  16. package/dist/cli/commands/diff.js +288 -0
  17. package/dist/cli/commands/help.js +63 -3
  18. package/dist/cli/commands/logs.d.ts +18 -0
  19. package/dist/cli/commands/logs.js +283 -0
  20. package/dist/cli/commands/pull.js +114 -10
  21. package/dist/cli/commands/push.js +122 -12
  22. package/dist/cli/commands/update-attribute.d.ts +3 -0
  23. package/dist/cli/commands/update-attribute.js +78 -0
  24. package/dist/cli/commands/watch.d.ts +6 -0
  25. package/dist/cli/commands/watch.js +195 -0
  26. package/dist/cli-new/bootstrap.d.ts +74 -0
  27. package/dist/cli-new/bootstrap.js +154 -0
  28. package/dist/cli-new/di/Container.d.ts +64 -0
  29. package/dist/cli-new/di/Container.js +122 -0
  30. package/dist/cli-new/di/tokens.d.ts +77 -0
  31. package/dist/cli-new/di/tokens.js +76 -0
  32. package/dist/cli.js +20 -0
  33. package/dist/domain/resources/common/types.d.ts +71 -0
  34. package/dist/domain/resources/common/types.js +42 -0
  35. package/dist/domain/strategies/sync/AkbSyncStrategy.d.ts +63 -0
  36. package/dist/domain/strategies/sync/AkbSyncStrategy.js +274 -0
  37. package/dist/domain/strategies/sync/AttributeSyncStrategy.d.ts +87 -0
  38. package/dist/domain/strategies/sync/AttributeSyncStrategy.js +378 -0
  39. package/dist/domain/strategies/sync/ConversationSyncStrategy.d.ts +61 -0
  40. package/dist/domain/strategies/sync/ConversationSyncStrategy.js +232 -0
  41. package/dist/domain/strategies/sync/ISyncStrategy.d.ts +149 -0
  42. package/dist/domain/strategies/sync/ISyncStrategy.js +24 -0
  43. package/dist/domain/strategies/sync/IntegrationSyncStrategy.d.ts +68 -0
  44. package/dist/domain/strategies/sync/IntegrationSyncStrategy.js +413 -0
  45. package/dist/domain/strategies/sync/ProjectSyncStrategy.d.ts +111 -0
  46. package/dist/domain/strategies/sync/ProjectSyncStrategy.js +523 -0
  47. package/dist/domain/strategies/sync/index.d.ts +13 -0
  48. package/dist/domain/strategies/sync/index.js +19 -0
  49. package/dist/sync/migrate.js +99 -23
  50. package/dist/types.d.ts +124 -0
  51. package/package.json +3 -1
  52. package/src/api.ts +53 -2
  53. package/src/application/migration/MigrationEngine.ts +492 -0
  54. package/src/application/migration/index.ts +5 -0
  55. package/src/application/sync/SyncEngine.ts +467 -0
  56. package/src/application/sync/index.ts +5 -0
  57. package/src/cli/commands/create-attribute.ts +1 -1
  58. package/src/cli/commands/create-customer.ts +185 -0
  59. package/src/cli/commands/diff.ts +360 -0
  60. package/src/cli/commands/help.ts +63 -3
  61. package/src/cli/commands/logs.ts +329 -0
  62. package/src/cli/commands/pull.ts +128 -11
  63. package/src/cli/commands/push.ts +131 -13
  64. package/src/cli/commands/update-attribute.ts +82 -0
  65. package/src/cli/commands/watch.ts +227 -0
  66. package/src/cli-new/bootstrap.ts +252 -0
  67. package/src/cli-new/di/Container.ts +152 -0
  68. package/src/cli-new/di/tokens.ts +105 -0
  69. package/src/cli.ts +25 -0
  70. package/src/domain/resources/common/types.ts +106 -0
  71. package/src/domain/strategies/sync/AkbSyncStrategy.ts +358 -0
  72. package/src/domain/strategies/sync/AttributeSyncStrategy.ts +508 -0
  73. package/src/domain/strategies/sync/ConversationSyncStrategy.ts +299 -0
  74. package/src/domain/strategies/sync/ISyncStrategy.ts +182 -0
  75. package/src/domain/strategies/sync/IntegrationSyncStrategy.ts +522 -0
  76. package/src/domain/strategies/sync/ProjectSyncStrategy.ts +747 -0
  77. package/src/domain/strategies/sync/index.ts +46 -0
  78. package/src/sync/migrate.ts +103 -24
  79. package/src/types.ts +135 -0
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Watch command handler
3
+ *
4
+ * Watches for file changes and automatically pushes when changes are detected.
5
+ * Supports selective resource watching with --only and --exclude flags.
6
+ *
7
+ * Usage:
8
+ * newo watch # Watch and push all changes
9
+ * newo watch --only projects # Watch only project files
10
+ * newo watch --debounce 2000 # Custom debounce delay (ms)
11
+ */
12
+ import { selectSingleCustomer } from '../customer-selection.js';
13
+ import { setupCli } from '../../cli-new/bootstrap.js';
14
+ import { PUSHABLE_RESOURCE_TYPES } from '../../cli-new/di/tokens.js';
15
+ import chokidar from 'chokidar';
16
+ import path from 'path';
17
+ // Default debounce delay in milliseconds
18
+ const DEFAULT_DEBOUNCE_MS = 1000;
19
+ /**
20
+ * Parse resource list from comma-separated string
21
+ */
22
+ function parseResourceList(input) {
23
+ if (!input)
24
+ return [];
25
+ return input.split(',').map(r => r.trim().toLowerCase()).filter(Boolean);
26
+ }
27
+ /**
28
+ * Get file patterns to watch based on resource types
29
+ */
30
+ function getWatchPatterns(customerDir, resources) {
31
+ const patterns = [];
32
+ for (const resource of resources) {
33
+ switch (resource) {
34
+ case 'projects':
35
+ // Watch .guidance and .jinja files in projects
36
+ patterns.push(path.join(customerDir, 'projects', '**', '*.guidance'));
37
+ patterns.push(path.join(customerDir, 'projects', '**', '*.jinja'));
38
+ patterns.push(path.join(customerDir, 'projects', '**', 'metadata.yaml'));
39
+ break;
40
+ case 'attributes':
41
+ // Watch attributes.yaml files
42
+ patterns.push(path.join(customerDir, 'attributes.yaml'));
43
+ patterns.push(path.join(customerDir, 'projects', '*', 'attributes.yaml'));
44
+ break;
45
+ case 'integrations':
46
+ // Watch integration files
47
+ patterns.push(path.join(customerDir, 'integrations', '**', '*.yaml'));
48
+ break;
49
+ case 'akb':
50
+ // Watch AKB files
51
+ patterns.push(path.join(customerDir, 'akb', '**', '*.yaml'));
52
+ break;
53
+ }
54
+ }
55
+ return patterns;
56
+ }
57
+ /**
58
+ * Push with V2 engine for selective resources
59
+ */
60
+ async function pushWithV2Engine(customerConfig, customer, resources, verbose) {
61
+ const { syncEngine, logger } = setupCli(customerConfig, verbose);
62
+ const result = await syncEngine.pushSelected(customer, resources);
63
+ if (result.totalCreated > 0 || result.totalUpdated > 0 || result.totalDeleted > 0) {
64
+ logger.info(`✅ Pushed: ${result.totalCreated} created, ${result.totalUpdated} updated, ${result.totalDeleted} deleted`);
65
+ }
66
+ if (result.errors.length > 0) {
67
+ logger.warn(`⚠️ ${result.errors.length} error(s) occurred`);
68
+ result.errors.forEach(e => logger.error(` ${e}`));
69
+ }
70
+ }
71
+ /**
72
+ * Main watch command handler
73
+ */
74
+ export async function handleWatchCommand(customerConfig, args, verbose) {
75
+ const { selectedCustomer } = selectSingleCustomer(customerConfig, args.customer);
76
+ if (!selectedCustomer) {
77
+ console.error('❌ Please specify a customer with --customer <idn> or set a default');
78
+ process.exit(1);
79
+ }
80
+ // Parse options
81
+ const onlyResources = parseResourceList(args.only);
82
+ const excludeResources = parseResourceList(args.exclude);
83
+ const debounceMs = typeof args.debounce === 'number'
84
+ ? args.debounce
85
+ : (typeof args.debounce === 'string' ? parseInt(args.debounce, 10) : DEFAULT_DEBOUNCE_MS);
86
+ // Determine resources to watch
87
+ let resourcesToWatch;
88
+ if (onlyResources.length > 0) {
89
+ resourcesToWatch = onlyResources.filter(r => PUSHABLE_RESOURCE_TYPES.includes(r));
90
+ }
91
+ else if (excludeResources.length > 0) {
92
+ resourcesToWatch = PUSHABLE_RESOURCE_TYPES.filter(r => !excludeResources.includes(r));
93
+ }
94
+ else {
95
+ resourcesToWatch = [...PUSHABLE_RESOURCE_TYPES];
96
+ }
97
+ if (resourcesToWatch.length === 0) {
98
+ console.error('❌ No valid resources to watch');
99
+ console.error(` Available: ${PUSHABLE_RESOURCE_TYPES.join(', ')}`);
100
+ process.exit(1);
101
+ }
102
+ const customerDir = path.join(process.cwd(), 'newo_customers', selectedCustomer.idn);
103
+ const watchPatterns = getWatchPatterns(customerDir, resourcesToWatch);
104
+ console.log(`👀 Watching for changes in: ${resourcesToWatch.join(', ')}`);
105
+ console.log(`📁 Customer: ${selectedCustomer.idn}`);
106
+ console.log(`⏱️ Debounce: ${debounceMs}ms`);
107
+ console.log('');
108
+ console.log('Press Ctrl+C to stop watching.');
109
+ console.log('');
110
+ // Debounce state
111
+ let debounceTimer = null;
112
+ let pendingChanges = new Set();
113
+ let isPushing = false;
114
+ // Push function with debouncing
115
+ const debouncedPush = () => {
116
+ if (debounceTimer) {
117
+ clearTimeout(debounceTimer);
118
+ }
119
+ debounceTimer = setTimeout(async () => {
120
+ if (isPushing) {
121
+ // If already pushing, wait and try again
122
+ debouncedPush();
123
+ return;
124
+ }
125
+ if (pendingChanges.size === 0) {
126
+ return;
127
+ }
128
+ const changedFiles = Array.from(pendingChanges);
129
+ pendingChanges.clear();
130
+ isPushing = true;
131
+ console.log(`\n🔄 Changes detected in ${changedFiles.length} file(s):`);
132
+ changedFiles.slice(0, 5).forEach(f => console.log(` ${path.relative(process.cwd(), f)}`));
133
+ if (changedFiles.length > 5) {
134
+ console.log(` ... and ${changedFiles.length - 5} more`);
135
+ }
136
+ try {
137
+ // Use V2 engine for selective push
138
+ await pushWithV2Engine(customerConfig, selectedCustomer, resourcesToWatch, verbose);
139
+ console.log('✅ Push completed');
140
+ }
141
+ catch (error) {
142
+ console.error('❌ Push failed:', error instanceof Error ? error.message : String(error));
143
+ }
144
+ finally {
145
+ isPushing = false;
146
+ }
147
+ }, debounceMs);
148
+ };
149
+ // Set up file watcher
150
+ const watcher = chokidar.watch(watchPatterns, {
151
+ persistent: true,
152
+ ignoreInitial: true,
153
+ awaitWriteFinish: {
154
+ stabilityThreshold: 300,
155
+ pollInterval: 100
156
+ }
157
+ });
158
+ watcher
159
+ .on('change', (filePath) => {
160
+ pendingChanges.add(filePath);
161
+ if (verbose) {
162
+ console.log(`📝 Changed: ${path.relative(process.cwd(), filePath)}`);
163
+ }
164
+ debouncedPush();
165
+ })
166
+ .on('add', (filePath) => {
167
+ pendingChanges.add(filePath);
168
+ if (verbose) {
169
+ console.log(`➕ Added: ${path.relative(process.cwd(), filePath)}`);
170
+ }
171
+ debouncedPush();
172
+ })
173
+ .on('unlink', (filePath) => {
174
+ pendingChanges.add(filePath);
175
+ if (verbose) {
176
+ console.log(`➖ Removed: ${path.relative(process.cwd(), filePath)}`);
177
+ }
178
+ debouncedPush();
179
+ })
180
+ .on('error', (error) => {
181
+ console.error('❌ Watcher error:', error);
182
+ });
183
+ // Handle graceful shutdown
184
+ process.on('SIGINT', () => {
185
+ console.log('\n\n👋 Stopping watch...');
186
+ watcher.close();
187
+ if (debounceTimer) {
188
+ clearTimeout(debounceTimer);
189
+ }
190
+ process.exit(0);
191
+ });
192
+ // Keep the process running
193
+ await new Promise(() => { }); // Never resolves - keeps process alive
194
+ }
195
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Bootstrap - Application Initialization and DI Setup
3
+ *
4
+ * This file wires all dependencies together and creates the service container.
5
+ * It's the single entry point for configuring the application.
6
+ */
7
+ import { ServiceContainer } from './di/Container.js';
8
+ import { type ILogger, type CustomerConfig, type MultiCustomerConfig } from '../domain/resources/common/types.js';
9
+ import { SyncEngine, type SyncEngineOptions } from '../application/sync/SyncEngine.js';
10
+ import { MigrationEngine } from '../application/migration/MigrationEngine.js';
11
+ import type { AxiosInstance } from 'axios';
12
+ /**
13
+ * API Client Factory that creates authenticated clients
14
+ */
15
+ export declare function createApiClient(customer: CustomerConfig, verbose: boolean): Promise<AxiosInstance>;
16
+ /**
17
+ * Bootstrap options
18
+ */
19
+ export interface BootstrapOptions {
20
+ /**
21
+ * Enable verbose logging
22
+ */
23
+ verbose?: boolean;
24
+ /**
25
+ * Sync engine options
26
+ */
27
+ syncEngineOptions?: SyncEngineOptions;
28
+ }
29
+ /**
30
+ * Create and configure the service container
31
+ */
32
+ export declare function createServiceContainer(customerConfig: MultiCustomerConfig, options?: BootstrapOptions): ServiceContainer;
33
+ /**
34
+ * Get SyncEngine from container
35
+ */
36
+ export declare function getSyncEngine(container: ServiceContainer): SyncEngine;
37
+ /**
38
+ * Get MigrationEngine from container
39
+ */
40
+ export declare function getMigrationEngine(container: ServiceContainer): MigrationEngine;
41
+ /**
42
+ * Get Logger from container
43
+ */
44
+ export declare function getLogger(container: ServiceContainer): ILogger;
45
+ /**
46
+ * Quick setup for CLI commands
47
+ *
48
+ * Creates a configured container with all services ready to use.
49
+ */
50
+ export declare function setupCli(customerConfig: MultiCustomerConfig, verbose?: boolean): {
51
+ container: ServiceContainer;
52
+ syncEngine: SyncEngine;
53
+ migrationEngine: MigrationEngine;
54
+ logger: ILogger;
55
+ };
56
+ /**
57
+ * Adapter function for legacy pull command
58
+ *
59
+ * This provides backward compatibility with the existing CLI.
60
+ */
61
+ export declare function legacyPullAdapter(customerConfig: MultiCustomerConfig, customer: CustomerConfig, verbose: boolean, silentOverwrite: boolean): Promise<void>;
62
+ /**
63
+ * Adapter function for legacy push command
64
+ */
65
+ export declare function legacyPushAdapter(customerConfig: MultiCustomerConfig, customer: CustomerConfig, verbose: boolean): Promise<void>;
66
+ /**
67
+ * Adapter function for legacy status command
68
+ */
69
+ export declare function legacyStatusAdapter(customerConfig: MultiCustomerConfig, customer: CustomerConfig, verbose: boolean): Promise<void>;
70
+ /**
71
+ * Adapter function for legacy migrate command
72
+ */
73
+ export declare function legacyMigrateAdapter(customerConfig: MultiCustomerConfig, sourceCustomer: CustomerConfig, destCustomer: CustomerConfig, sourceClient: AxiosInstance, destClient: AxiosInstance, verbose: boolean): Promise<void>;
74
+ //# sourceMappingURL=bootstrap.d.ts.map
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Bootstrap - Application Initialization and DI Setup
3
+ *
4
+ * This file wires all dependencies together and creates the service container.
5
+ * It's the single entry point for configuring the application.
6
+ */
7
+ import { ServiceContainer } from './di/Container.js';
8
+ import { TOKENS } from './di/tokens.js';
9
+ import { ConsoleLogger } from '../domain/resources/common/types.js';
10
+ import { SyncEngine } from '../application/sync/SyncEngine.js';
11
+ import { MigrationEngine, TransformService } from '../application/migration/MigrationEngine.js';
12
+ import { ProjectSyncStrategy, createProjectSyncStrategy } from '../domain/strategies/sync/ProjectSyncStrategy.js';
13
+ import { AttributeSyncStrategy, createAttributeSyncStrategy } from '../domain/strategies/sync/AttributeSyncStrategy.js';
14
+ import { IntegrationSyncStrategy, createIntegrationSyncStrategy } from '../domain/strategies/sync/IntegrationSyncStrategy.js';
15
+ import { AkbSyncStrategy, createAkbSyncStrategy } from '../domain/strategies/sync/AkbSyncStrategy.js';
16
+ import { ConversationSyncStrategy, createConversationSyncStrategy } from '../domain/strategies/sync/ConversationSyncStrategy.js';
17
+ import { makeClient } from '../api.js';
18
+ import { getValidAccessToken } from '../auth.js';
19
+ /**
20
+ * API Client Factory that creates authenticated clients
21
+ */
22
+ export async function createApiClient(customer, verbose) {
23
+ // Set environment variables for the customer
24
+ process.env.NEWO_API_KEY = customer.apiKey;
25
+ if (customer.projectId) {
26
+ process.env.NEWO_PROJECT_ID = customer.projectId;
27
+ }
28
+ const token = await getValidAccessToken();
29
+ return makeClient(verbose, token);
30
+ }
31
+ /**
32
+ * Create and configure the service container
33
+ */
34
+ export function createServiceContainer(customerConfig, options = {}) {
35
+ const container = new ServiceContainer();
36
+ const verbose = options.verbose ?? false;
37
+ // === Infrastructure Layer ===
38
+ // Logger
39
+ const logger = new ConsoleLogger(verbose);
40
+ container.registerValue(TOKENS.LOGGER, logger);
41
+ // Customer Config
42
+ container.registerValue(TOKENS.CUSTOMER_CONFIG, customerConfig);
43
+ // API Client Factory
44
+ container.registerValue(TOKENS.API_CLIENT_FACTORY, createApiClient);
45
+ // === Domain Layer - Sync Strategies ===
46
+ // Project Sync Strategy
47
+ container.registerSingleton(TOKENS.PROJECT_SYNC_STRATEGY, () => createProjectSyncStrategy(createApiClient, container.get(TOKENS.LOGGER)));
48
+ // Attribute Sync Strategy
49
+ container.registerSingleton(TOKENS.ATTRIBUTE_SYNC_STRATEGY, () => createAttributeSyncStrategy(createApiClient, container.get(TOKENS.LOGGER)));
50
+ // Integration Sync Strategy
51
+ container.registerSingleton(TOKENS.INTEGRATION_SYNC_STRATEGY, () => createIntegrationSyncStrategy(createApiClient, container.get(TOKENS.LOGGER)));
52
+ // AKB Sync Strategy
53
+ container.registerSingleton(TOKENS.AKB_SYNC_STRATEGY, () => createAkbSyncStrategy(createApiClient, container.get(TOKENS.LOGGER)));
54
+ // Conversation Sync Strategy
55
+ container.registerSingleton(TOKENS.CONVERSATION_SYNC_STRATEGY, () => createConversationSyncStrategy(createApiClient, container.get(TOKENS.LOGGER)));
56
+ // === Application Layer ===
57
+ // Sync Engine (uses all sync strategies)
58
+ container.registerSingleton(TOKENS.SYNC_ENGINE, () => {
59
+ const strategies = [
60
+ container.get(TOKENS.PROJECT_SYNC_STRATEGY),
61
+ container.get(TOKENS.ATTRIBUTE_SYNC_STRATEGY),
62
+ container.get(TOKENS.INTEGRATION_SYNC_STRATEGY),
63
+ container.get(TOKENS.AKB_SYNC_STRATEGY),
64
+ container.get(TOKENS.CONVERSATION_SYNC_STRATEGY),
65
+ ];
66
+ return new SyncEngine(strategies, container.get(TOKENS.LOGGER), options.syncEngineOptions);
67
+ });
68
+ // Migration Engine (uses SyncEngine)
69
+ container.registerSingleton(TOKENS.MIGRATION_ENGINE, () => {
70
+ const syncEngine = container.get(TOKENS.SYNC_ENGINE);
71
+ const transformService = new TransformService(container.get(TOKENS.LOGGER));
72
+ return new MigrationEngine(syncEngine, transformService, container.get(TOKENS.LOGGER));
73
+ });
74
+ return container;
75
+ }
76
+ /**
77
+ * Get SyncEngine from container
78
+ */
79
+ export function getSyncEngine(container) {
80
+ return container.get(TOKENS.SYNC_ENGINE);
81
+ }
82
+ /**
83
+ * Get MigrationEngine from container
84
+ */
85
+ export function getMigrationEngine(container) {
86
+ return container.get(TOKENS.MIGRATION_ENGINE);
87
+ }
88
+ /**
89
+ * Get Logger from container
90
+ */
91
+ export function getLogger(container) {
92
+ return container.get(TOKENS.LOGGER);
93
+ }
94
+ /**
95
+ * Quick setup for CLI commands
96
+ *
97
+ * Creates a configured container with all services ready to use.
98
+ */
99
+ export function setupCli(customerConfig, verbose = false) {
100
+ const container = createServiceContainer(customerConfig, { verbose });
101
+ return {
102
+ container,
103
+ syncEngine: getSyncEngine(container),
104
+ migrationEngine: getMigrationEngine(container),
105
+ logger: getLogger(container)
106
+ };
107
+ }
108
+ /**
109
+ * Adapter function for legacy pull command
110
+ *
111
+ * This provides backward compatibility with the existing CLI.
112
+ */
113
+ export async function legacyPullAdapter(customerConfig, customer, verbose, silentOverwrite) {
114
+ const { syncEngine } = setupCli(customerConfig, verbose);
115
+ await syncEngine.pullAll(customer, {
116
+ silentOverwrite,
117
+ verbose
118
+ });
119
+ }
120
+ /**
121
+ * Adapter function for legacy push command
122
+ */
123
+ export async function legacyPushAdapter(customerConfig, customer, verbose) {
124
+ const { syncEngine } = setupCli(customerConfig, verbose);
125
+ await syncEngine.pushAll(customer);
126
+ }
127
+ /**
128
+ * Adapter function for legacy status command
129
+ */
130
+ export async function legacyStatusAdapter(customerConfig, customer, verbose) {
131
+ const { syncEngine, logger } = setupCli(customerConfig, verbose);
132
+ const status = await syncEngine.getStatus(customer);
133
+ logger.info(`\nStatus for customer: ${status.customer}`);
134
+ logger.info(`Total changes: ${status.totalChanges}\n`);
135
+ for (const resource of status.resources) {
136
+ if (resource.changedCount > 0) {
137
+ logger.info(`${resource.displayName}: ${resource.changedCount} change(s)`);
138
+ for (const change of resource.changes) {
139
+ logger.info(` ${change.operation.toUpperCase()[0]} ${change.path}`);
140
+ }
141
+ }
142
+ }
143
+ if (status.totalChanges === 0) {
144
+ logger.info('No changes to push.');
145
+ }
146
+ }
147
+ /**
148
+ * Adapter function for legacy migrate command
149
+ */
150
+ export async function legacyMigrateAdapter(customerConfig, sourceCustomer, destCustomer, sourceClient, destClient, verbose) {
151
+ const { migrationEngine } = setupCli(customerConfig, verbose);
152
+ await migrationEngine.migrateAccount(sourceCustomer, destCustomer, sourceClient, destClient, { verbose });
153
+ }
154
+ //# sourceMappingURL=bootstrap.js.map
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Dependency Injection Container
3
+ *
4
+ * A simple, TypeScript-native DI container that:
5
+ * - Supports singleton and factory registrations
6
+ * - Provides type-safe dependency resolution
7
+ * - Enables easy testing through dependency injection
8
+ */
9
+ /**
10
+ * Factory function type for creating service instances
11
+ */
12
+ type Factory<T> = (container: ServiceContainer) => T;
13
+ /**
14
+ * Service Container for Dependency Injection
15
+ */
16
+ export declare class ServiceContainer {
17
+ private registrations;
18
+ /**
19
+ * Register a factory that creates a new instance each time
20
+ */
21
+ register<T>(token: symbol, factory: Factory<T>): void;
22
+ /**
23
+ * Register a singleton - only created once
24
+ */
25
+ registerSingleton<T>(token: symbol, instanceOrFactory: T | Factory<T>): void;
26
+ /**
27
+ * Register a value directly
28
+ */
29
+ registerValue<T>(token: symbol, value: T): void;
30
+ /**
31
+ * Resolve a service by its token
32
+ */
33
+ get<T>(token: symbol): T;
34
+ /**
35
+ * Check if a token is registered
36
+ */
37
+ has(token: symbol): boolean;
38
+ /**
39
+ * Get all registered tokens
40
+ */
41
+ getTokens(): symbol[];
42
+ /**
43
+ * Clear all registrations (useful for testing)
44
+ */
45
+ clear(): void;
46
+ /**
47
+ * Create a child container that inherits parent registrations
48
+ */
49
+ createChild(): ServiceContainer;
50
+ }
51
+ /**
52
+ * Get the global container instance
53
+ */
54
+ export declare function getContainer(): ServiceContainer;
55
+ /**
56
+ * Set the global container instance (useful for testing)
57
+ */
58
+ export declare function setContainer(container: ServiceContainer): void;
59
+ /**
60
+ * Reset the global container (useful for testing)
61
+ */
62
+ export declare function resetContainer(): void;
63
+ export {};
64
+ //# sourceMappingURL=Container.d.ts.map
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Dependency Injection Container
3
+ *
4
+ * A simple, TypeScript-native DI container that:
5
+ * - Supports singleton and factory registrations
6
+ * - Provides type-safe dependency resolution
7
+ * - Enables easy testing through dependency injection
8
+ */
9
+ /**
10
+ * Service Container for Dependency Injection
11
+ */
12
+ export class ServiceContainer {
13
+ registrations = new Map();
14
+ /**
15
+ * Register a factory that creates a new instance each time
16
+ */
17
+ register(token, factory) {
18
+ this.registrations.set(token, {
19
+ factory,
20
+ singleton: false
21
+ });
22
+ }
23
+ /**
24
+ * Register a singleton - only created once
25
+ */
26
+ registerSingleton(token, instanceOrFactory) {
27
+ if (typeof instanceOrFactory === 'function') {
28
+ this.registrations.set(token, {
29
+ factory: instanceOrFactory,
30
+ singleton: true
31
+ });
32
+ }
33
+ else {
34
+ this.registrations.set(token, {
35
+ factory: () => instanceOrFactory,
36
+ singleton: true,
37
+ instance: instanceOrFactory
38
+ });
39
+ }
40
+ }
41
+ /**
42
+ * Register a value directly
43
+ */
44
+ registerValue(token, value) {
45
+ this.registrations.set(token, {
46
+ factory: () => value,
47
+ singleton: true,
48
+ instance: value
49
+ });
50
+ }
51
+ /**
52
+ * Resolve a service by its token
53
+ */
54
+ get(token) {
55
+ const registration = this.registrations.get(token);
56
+ if (!registration) {
57
+ throw new Error(`No registration found for token: ${token.toString()}`);
58
+ }
59
+ if (registration.singleton) {
60
+ if (registration.instance === undefined) {
61
+ registration.instance = registration.factory(this);
62
+ }
63
+ return registration.instance;
64
+ }
65
+ return registration.factory(this);
66
+ }
67
+ /**
68
+ * Check if a token is registered
69
+ */
70
+ has(token) {
71
+ return this.registrations.has(token);
72
+ }
73
+ /**
74
+ * Get all registered tokens
75
+ */
76
+ getTokens() {
77
+ return Array.from(this.registrations.keys());
78
+ }
79
+ /**
80
+ * Clear all registrations (useful for testing)
81
+ */
82
+ clear() {
83
+ this.registrations.clear();
84
+ }
85
+ /**
86
+ * Create a child container that inherits parent registrations
87
+ */
88
+ createChild() {
89
+ const child = new ServiceContainer();
90
+ // Copy parent registrations
91
+ for (const [token, registration] of this.registrations) {
92
+ child.registrations.set(token, { ...registration });
93
+ }
94
+ return child;
95
+ }
96
+ }
97
+ /**
98
+ * Global container instance
99
+ */
100
+ let globalContainer = null;
101
+ /**
102
+ * Get the global container instance
103
+ */
104
+ export function getContainer() {
105
+ if (!globalContainer) {
106
+ globalContainer = new ServiceContainer();
107
+ }
108
+ return globalContainer;
109
+ }
110
+ /**
111
+ * Set the global container instance (useful for testing)
112
+ */
113
+ export function setContainer(container) {
114
+ globalContainer = container;
115
+ }
116
+ /**
117
+ * Reset the global container (useful for testing)
118
+ */
119
+ export function resetContainer() {
120
+ globalContainer = null;
121
+ }
122
+ //# sourceMappingURL=Container.js.map
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Dependency Injection Tokens
3
+ *
4
+ * These symbols are used as unique identifiers for services in the DI container.
5
+ * Using symbols ensures no naming conflicts.
6
+ */
7
+ export declare const TOKENS: {
8
+ readonly LOGGER: symbol;
9
+ readonly AUTH_SERVICE: symbol;
10
+ readonly API_CLIENT: symbol;
11
+ readonly API_CLIENT_FACTORY: symbol;
12
+ readonly FILE_SYSTEM: symbol;
13
+ readonly HASH_MANAGER: symbol;
14
+ readonly METADATA_GENERATOR: symbol;
15
+ readonly PROJECT_REPOSITORY: symbol;
16
+ readonly INTEGRATION_REPOSITORY: symbol;
17
+ readonly AKB_REPOSITORY: symbol;
18
+ readonly ATTRIBUTE_REPOSITORY: symbol;
19
+ readonly CONVERSATION_REPOSITORY: symbol;
20
+ readonly PROJECT_SYNC_STRATEGY: symbol;
21
+ readonly INTEGRATION_SYNC_STRATEGY: symbol;
22
+ readonly AKB_SYNC_STRATEGY: symbol;
23
+ readonly ATTRIBUTE_SYNC_STRATEGY: symbol;
24
+ readonly CONVERSATION_SYNC_STRATEGY: symbol;
25
+ readonly PROJECT_ENTITY_STRATEGY: symbol;
26
+ readonly AGENT_ENTITY_STRATEGY: symbol;
27
+ readonly FLOW_ENTITY_STRATEGY: symbol;
28
+ readonly SKILL_ENTITY_STRATEGY: symbol;
29
+ readonly SYNC_ENGINE: symbol;
30
+ readonly MIGRATION_ENGINE: symbol;
31
+ readonly ENTITY_MANAGER: symbol;
32
+ readonly PULL_USE_CASE: symbol;
33
+ readonly PUSH_USE_CASE: symbol;
34
+ readonly STATUS_USE_CASE: symbol;
35
+ readonly MIGRATE_USE_CASE: symbol;
36
+ readonly CREATE_ENTITY_USE_CASE: symbol;
37
+ readonly DELETE_ENTITY_USE_CASE: symbol;
38
+ readonly COMMAND_REGISTRY: symbol;
39
+ readonly COMMAND_EXECUTOR: symbol;
40
+ readonly ERROR_HANDLER: symbol;
41
+ readonly CUSTOMER_SELECTOR: symbol;
42
+ readonly CUSTOMER_CONFIG: symbol;
43
+ readonly ENVIRONMENT: symbol;
44
+ };
45
+ /**
46
+ * Type for the tokens object
47
+ */
48
+ export type TokenKey = keyof typeof TOKENS;
49
+ export type Token = (typeof TOKENS)[TokenKey];
50
+ /**
51
+ * Resource types for selective sync
52
+ * These match the resourceType property in each ISyncStrategy implementation
53
+ */
54
+ export declare const RESOURCE_TYPES: {
55
+ readonly PROJECTS: "projects";
56
+ readonly ATTRIBUTES: "attributes";
57
+ readonly INTEGRATIONS: "integrations";
58
+ readonly AKB: "akb";
59
+ readonly CONVERSATIONS: "conversations";
60
+ };
61
+ /**
62
+ * All available resource types for sync operations
63
+ */
64
+ export declare const ALL_RESOURCE_TYPES: ("projects" | "integrations" | "akb" | "attributes" | "conversations")[];
65
+ /**
66
+ * Pushable resource types (excludes read-only resources like conversations)
67
+ */
68
+ export declare const PUSHABLE_RESOURCE_TYPES: readonly ["projects", "attributes", "integrations", "akb"];
69
+ /**
70
+ * Type for resource type values
71
+ */
72
+ export type ResourceType = (typeof RESOURCE_TYPES)[keyof typeof RESOURCE_TYPES];
73
+ /**
74
+ * Type for pushable resource types
75
+ */
76
+ export type PushableResourceType = (typeof PUSHABLE_RESOURCE_TYPES)[number];
77
+ //# sourceMappingURL=tokens.d.ts.map