@atmyapp/cli 0.0.2 → 0.0.4
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 +138 -55
- package/dist/cli/commands/migrate.js +55 -10
- package/dist/cli/utils/content-processor.js +16 -7
- package/dist/cli/utils/definition-processor.js +7 -4
- package/dist/cli/utils/index.d.ts +2 -0
- package/dist/cli/utils/index.js +2 -0
- package/dist/cli/utils/parallel-schema-processor.d.ts +5 -0
- package/dist/cli/utils/parallel-schema-processor.js +147 -0
- package/dist/cli/utils/schema-processor.js +138 -16
- package/dist/cli/utils/worker-file-processor.d.ts +7 -0
- package/dist/cli/utils/worker-file-processor.js +255 -0
- package/dist/cli/utils/worker-pool.d.ts +25 -0
- package/dist/cli/utils/worker-pool.js +126 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://opensource.org/licenses/ISC)
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
|
|
7
|
-
> 🔧 **Migrate your TypeScript definitions seamlessly.** The official CLI tool for AtMyApp - AI-powered content management that migrates your type definitions to the AtMyApp platform with zero configuration.
|
|
7
|
+
> 🔧 **Migrate your TypeScript definitions seamlessly.** The official CLI tool for AtMyApp - AI-powered content management that migrates your type definitions to the AtMyApp platform with zero configuration and lightning-fast parallel processing.
|
|
8
8
|
|
|
9
9
|
## 📖 Table of Contents
|
|
10
10
|
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
- [📚 Commands](#-commands)
|
|
15
15
|
- [use Command](#use-command)
|
|
16
16
|
- [migrate Command](#migrate-command)
|
|
17
|
+
- [⚡ Performance Features](#-performance-features)
|
|
17
18
|
- [🎯 Type Definitions](#-type-definitions)
|
|
18
19
|
- [Content Definitions](#content-definitions)
|
|
19
20
|
- [Event Definitions](#event-definitions)
|
|
@@ -31,10 +32,12 @@
|
|
|
31
32
|
📊 **Event Analytics Support** - Built-in support for event tracking definitions
|
|
32
33
|
🖼️ **Media Type Support** - Handles image and file definitions with optimization configs
|
|
33
34
|
🔄 **Real-time Processing** - Process multiple definition files simultaneously
|
|
35
|
+
⚡ **Lightning Fast** - Multi-threaded parallel processing for large codebases
|
|
34
36
|
🎯 **Type-Safe** - Full TypeScript support with comprehensive validation
|
|
35
|
-
|
|
37
|
+
🚀 **Zero Configuration** - Works out of the box with smart defaults
|
|
36
38
|
🔐 **Secure** - API key authentication with session management
|
|
37
|
-
🌊 **Pipeline Architecture** - Extensible processing pipeline for custom transformations
|
|
39
|
+
🌊 **Pipeline Architecture** - Extensible processing pipeline for custom transformations
|
|
40
|
+
📊 **Performance Monitoring** - Built-in timing and performance metrics
|
|
38
41
|
|
|
39
42
|
## 📦 Installation
|
|
40
43
|
|
|
@@ -55,7 +58,7 @@ pnpm add -g @atmyapp/cli
|
|
|
55
58
|
# 1. Authenticate with your AtMyApp project
|
|
56
59
|
ama use --token your-api-token --url https://your-project.atmyapp.com
|
|
57
60
|
|
|
58
|
-
# 2. Migrate your definitions
|
|
61
|
+
# 2. Migrate your definitions with parallel processing
|
|
59
62
|
ama migrate
|
|
60
63
|
|
|
61
64
|
# 3. Or run in dry-run mode to preview changes
|
|
@@ -92,7 +95,7 @@ ama use --token "ama_pk_..." --url "https://edge.atmyapp.com/projects/your-proje
|
|
|
92
95
|
|
|
93
96
|
### migrate Command
|
|
94
97
|
|
|
95
|
-
Migrate TypeScript definitions to the AtMyApp platform.
|
|
98
|
+
Migrate TypeScript definitions to the AtMyApp platform with optimized parallel processing.
|
|
96
99
|
|
|
97
100
|
```bash
|
|
98
101
|
ama migrate [options]
|
|
@@ -104,19 +107,78 @@ ama migrate [options]
|
|
|
104
107
|
- `--verbose` - Enable verbose logging (default: false)
|
|
105
108
|
- `--tsconfig <path>` - Path to tsconfig.json (default: "tsconfig.json")
|
|
106
109
|
- `--continue-on-error` - Continue processing even if some files fail (default: false)
|
|
110
|
+
- `--parallel` - Enable parallel processing using worker threads (default: true)
|
|
111
|
+
- `--max-workers <number>` - Maximum number of worker threads (default: CPU cores, max 8)
|
|
112
|
+
- `--no-filtering` - Disable file pre-filtering optimization (default: false)
|
|
107
113
|
|
|
108
114
|
**Examples:**
|
|
109
115
|
|
|
110
116
|
```bash
|
|
111
|
-
# Basic migration
|
|
117
|
+
# Basic migration with parallel processing (default)
|
|
112
118
|
ama migrate
|
|
113
119
|
|
|
114
|
-
# Dry run with verbose output
|
|
120
|
+
# Dry run with verbose output and performance metrics
|
|
115
121
|
ama migrate --dry-run --verbose
|
|
116
122
|
|
|
117
123
|
# Use custom tsconfig and continue on errors
|
|
118
124
|
ama migrate --tsconfig ./custom-tsconfig.json --continue-on-error
|
|
125
|
+
|
|
126
|
+
# Force sequential processing (slower, for debugging)
|
|
127
|
+
ama migrate --no-parallel
|
|
128
|
+
|
|
129
|
+
# Use specific number of worker threads
|
|
130
|
+
ama migrate --max-workers 4
|
|
131
|
+
|
|
132
|
+
# Maximum performance for large codebases
|
|
133
|
+
ama migrate --max-workers 8 --verbose
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## ⚡ Performance Features
|
|
137
|
+
|
|
138
|
+
### Multi-threaded Processing
|
|
139
|
+
|
|
140
|
+
The CLI uses Node.js worker threads to process TypeScript files in parallel, providing significant performance improvements for large codebases:
|
|
141
|
+
|
|
142
|
+
- **Automatic scaling**: Uses optimal number of workers based on CPU cores
|
|
143
|
+
- **Smart filtering**: Pre-filters files to only process those with ATMYAPP exports
|
|
144
|
+
- **Program caching**: Reuses TypeScript compilation results across workers
|
|
145
|
+
- **Batch processing**: Groups schema generation for maximum efficiency
|
|
146
|
+
|
|
147
|
+
### Performance Optimizations
|
|
148
|
+
|
|
149
|
+
1. **File Pre-filtering**: Quickly scans files for ATMYAPP exports before processing
|
|
150
|
+
2. **Worker Pool Management**: Efficiently distributes work across available CPU cores
|
|
151
|
+
3. **TypeScript Program Caching**: Avoids redundant compilation overhead
|
|
152
|
+
4. **Parallel Schema Generation**: Processes multiple definition types simultaneously
|
|
153
|
+
5. **Chunked Processing**: Handles large file sets in optimized chunks
|
|
154
|
+
|
|
155
|
+
### Performance Monitoring
|
|
156
|
+
|
|
157
|
+
Enable verbose mode to see detailed performance metrics:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
ama migrate --verbose
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Sample Output:**
|
|
164
|
+
|
|
119
165
|
```
|
|
166
|
+
✅ Successfully processed 127 AMA contents in 2.34s
|
|
167
|
+
📊 Performance Summary:
|
|
168
|
+
Total time: 3.45s
|
|
169
|
+
Processing time: 2.34s
|
|
170
|
+
Files processed: 127
|
|
171
|
+
Processing mode: Parallel
|
|
172
|
+
Worker threads: 8
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Expected Performance Improvements
|
|
176
|
+
|
|
177
|
+
With parallel processing enabled (default), you can expect:
|
|
178
|
+
|
|
179
|
+
- **Small codebases** (< 50 files): 1.5-2x faster
|
|
180
|
+
- **Medium codebases** (50-200 files): 2-4x faster
|
|
181
|
+
- **Large codebases** (200+ files): 3-6x faster
|
|
120
182
|
|
|
121
183
|
## 🎯 Type Definitions
|
|
122
184
|
|
|
@@ -148,23 +210,23 @@ export type ATMYAPP = [BlogPostContent];
|
|
|
148
210
|
|
|
149
211
|
### Event Definitions
|
|
150
212
|
|
|
151
|
-
Define analytics events using `
|
|
213
|
+
Define analytics events using `AmaCustomEventDef` with ordered columns:
|
|
152
214
|
|
|
153
215
|
```typescript
|
|
154
|
-
import {
|
|
216
|
+
import { AmaCustomEventDef } from "@atmyapp/core";
|
|
155
217
|
|
|
156
218
|
// Define event types for analytics tracking
|
|
157
|
-
export type PageViewEvent =
|
|
219
|
+
export type PageViewEvent = AmaCustomEventDef<
|
|
158
220
|
"page_view",
|
|
159
221
|
["page", "referrer", "timestamp", "user_id"]
|
|
160
222
|
>;
|
|
161
223
|
|
|
162
|
-
export type PurchaseEvent =
|
|
224
|
+
export type PurchaseEvent = AmaCustomEventDef<
|
|
163
225
|
"purchase",
|
|
164
226
|
["product_id", "amount", "currency", "user_id", "timestamp"]
|
|
165
227
|
>;
|
|
166
228
|
|
|
167
|
-
export type ClickEvent =
|
|
229
|
+
export type ClickEvent = AmaCustomEventDef<
|
|
168
230
|
"button_click",
|
|
169
231
|
["element", "position", "timestamp"]
|
|
170
232
|
>;
|
|
@@ -213,13 +275,28 @@ export type UserManual = AmaFileDef<"/docs/manual.pdf">;
|
|
|
213
275
|
export type ATMYAPP = [HeroImage, UserManual];
|
|
214
276
|
```
|
|
215
277
|
|
|
278
|
+
### Icon Definitions
|
|
279
|
+
|
|
280
|
+
Define icons with `AmaIconDef` (simpler than images, no configuration needed):
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
import { AmaIconDef } from "@atmyapp/core";
|
|
284
|
+
|
|
285
|
+
// Icon definitions
|
|
286
|
+
export type MenuIcon = AmaIconDef<"/icons/menu">;
|
|
287
|
+
export type SearchIcon = AmaIconDef<"/icons/search">;
|
|
288
|
+
export type UserIcon = AmaIconDef<"/icons/user">;
|
|
289
|
+
|
|
290
|
+
export type ATMYAPP = [MenuIcon, SearchIcon, UserIcon];
|
|
291
|
+
```
|
|
292
|
+
|
|
216
293
|
## 💡 Examples
|
|
217
294
|
|
|
218
295
|
### 🏪 E-commerce Setup
|
|
219
296
|
|
|
220
297
|
```typescript
|
|
221
298
|
// types/ecommerce.ts
|
|
222
|
-
import { AmaContentDef,
|
|
299
|
+
import { AmaContentDef, AmaCustomEventDef, AmaImageDef } from "@atmyapp/core";
|
|
223
300
|
|
|
224
301
|
// Product catalog
|
|
225
302
|
interface Product {
|
|
@@ -243,18 +320,23 @@ export type ProductImage = AmaImageDef<
|
|
|
243
320
|
}
|
|
244
321
|
>;
|
|
245
322
|
|
|
323
|
+
// UI Icons
|
|
324
|
+
export type CartIcon = AmaIconDef<"/icons/cart">;
|
|
325
|
+
export type WishlistIcon = AmaIconDef<"/icons/wishlist">;
|
|
326
|
+
export type CompareIcon = AmaIconDef<"/icons/compare">;
|
|
327
|
+
|
|
246
328
|
// E-commerce events
|
|
247
|
-
export type ProductViewEvent =
|
|
329
|
+
export type ProductViewEvent = AmaCustomEventDef<
|
|
248
330
|
"product_view",
|
|
249
331
|
["product_id", "category", "price", "user_id", "timestamp"]
|
|
250
332
|
>;
|
|
251
333
|
|
|
252
|
-
export type AddToCartEvent =
|
|
334
|
+
export type AddToCartEvent = AmaCustomEventDef<
|
|
253
335
|
"add_to_cart",
|
|
254
336
|
["product_id", "quantity", "price", "user_id", "timestamp"]
|
|
255
337
|
>;
|
|
256
338
|
|
|
257
|
-
export type PurchaseEvent =
|
|
339
|
+
export type PurchaseEvent = AmaCustomEventDef<
|
|
258
340
|
"purchase",
|
|
259
341
|
["order_id", "total_amount", "currency", "user_id", "timestamp"]
|
|
260
342
|
>;
|
|
@@ -264,6 +346,9 @@ export type ATMYAPP = [
|
|
|
264
346
|
ProductCatalog,
|
|
265
347
|
FeaturedProduct,
|
|
266
348
|
ProductImage,
|
|
349
|
+
CartIcon,
|
|
350
|
+
WishlistIcon,
|
|
351
|
+
CompareIcon,
|
|
267
352
|
ProductViewEvent,
|
|
268
353
|
AddToCartEvent,
|
|
269
354
|
PurchaseEvent,
|
|
@@ -274,7 +359,12 @@ export type ATMYAPP = [
|
|
|
274
359
|
|
|
275
360
|
```typescript
|
|
276
361
|
// types/blog.ts
|
|
277
|
-
import {
|
|
362
|
+
import {
|
|
363
|
+
AmaContentDef,
|
|
364
|
+
AmaCustomEventDef,
|
|
365
|
+
AmaImageDef,
|
|
366
|
+
AmaIconDef,
|
|
367
|
+
} from "@atmyapp/core";
|
|
278
368
|
|
|
279
369
|
// Blog content types
|
|
280
370
|
interface BlogPost {
|
|
@@ -313,18 +403,23 @@ export type BlogHeroImage = AmaImageDef<
|
|
|
313
403
|
}
|
|
314
404
|
>;
|
|
315
405
|
|
|
406
|
+
// Blog UI icons
|
|
407
|
+
export type ShareIcon = AmaIconDef<"/icons/share">;
|
|
408
|
+
export type LikeIcon = AmaIconDef<"/icons/like">;
|
|
409
|
+
export type CommentIcon = AmaIconDef<"/icons/comment">;
|
|
410
|
+
|
|
316
411
|
// Blog analytics events
|
|
317
|
-
export type ArticleReadEvent =
|
|
412
|
+
export type ArticleReadEvent = AmaCustomEventDef<
|
|
318
413
|
"article_read",
|
|
319
414
|
["article_id", "reading_time", "completion_rate", "referrer", "timestamp"]
|
|
320
415
|
>;
|
|
321
416
|
|
|
322
|
-
export type CommentEvent =
|
|
417
|
+
export type CommentEvent = AmaCustomEventDef<
|
|
323
418
|
"comment_posted",
|
|
324
419
|
["article_id", "comment_id", "user_id", "timestamp"]
|
|
325
420
|
>;
|
|
326
421
|
|
|
327
|
-
export type ShareEvent =
|
|
422
|
+
export type ShareEvent = AmaCustomEventDef<
|
|
328
423
|
"article_shared",
|
|
329
424
|
["article_id", "platform", "user_id", "timestamp"]
|
|
330
425
|
>;
|
|
@@ -334,6 +429,9 @@ export type ATMYAPP = [
|
|
|
334
429
|
FeaturedPost,
|
|
335
430
|
Categories,
|
|
336
431
|
BlogHeroImage,
|
|
432
|
+
ShareIcon,
|
|
433
|
+
LikeIcon,
|
|
434
|
+
CommentIcon,
|
|
337
435
|
ArticleReadEvent,
|
|
338
436
|
CommentEvent,
|
|
339
437
|
ShareEvent,
|
|
@@ -344,36 +442,36 @@ export type ATMYAPP = [
|
|
|
344
442
|
|
|
345
443
|
```typescript
|
|
346
444
|
// types/analytics.ts
|
|
347
|
-
import {
|
|
445
|
+
import { AmaCustomEventDef } from "@atmyapp/core";
|
|
348
446
|
|
|
349
447
|
// User interaction events
|
|
350
|
-
export type PageViewEvent =
|
|
448
|
+
export type PageViewEvent = AmaCustomEventDef<
|
|
351
449
|
"page_view",
|
|
352
450
|
["page", "referrer", "user_agent", "session_id", "timestamp"]
|
|
353
451
|
>;
|
|
354
452
|
|
|
355
|
-
export type ClickEvent =
|
|
453
|
+
export type ClickEvent = AmaCustomEventDef<
|
|
356
454
|
"click",
|
|
357
455
|
["element", "element_text", "page", "position_x", "position_y", "timestamp"]
|
|
358
456
|
>;
|
|
359
457
|
|
|
360
|
-
export type FormSubmissionEvent =
|
|
458
|
+
export type FormSubmissionEvent = AmaCustomEventDef<
|
|
361
459
|
"form_submit",
|
|
362
460
|
["form_id", "form_name", "success", "validation_errors", "timestamp"]
|
|
363
461
|
>;
|
|
364
462
|
|
|
365
|
-
export type ScrollEvent =
|
|
463
|
+
export type ScrollEvent = AmaCustomEventDef<
|
|
366
464
|
"scroll",
|
|
367
465
|
["page", "scroll_depth", "session_id", "timestamp"]
|
|
368
466
|
>;
|
|
369
467
|
|
|
370
|
-
export type ErrorEvent =
|
|
468
|
+
export type ErrorEvent = AmaCustomEventDef<
|
|
371
469
|
"error",
|
|
372
470
|
["error_message", "error_stack", "page", "user_agent", "timestamp"]
|
|
373
471
|
>;
|
|
374
472
|
|
|
375
473
|
// Performance events
|
|
376
|
-
export type PerformanceEvent =
|
|
474
|
+
export type PerformanceEvent = AmaCustomEventDef<
|
|
377
475
|
"performance",
|
|
378
476
|
["page", "load_time", "dom_ready", "first_paint", "timestamp"]
|
|
379
477
|
>;
|
|
@@ -400,7 +498,8 @@ your-project/
|
|
|
400
498
|
├── types/
|
|
401
499
|
│ ├── content.ts # Content definitions
|
|
402
500
|
│ ├── events.ts # Event definitions
|
|
403
|
-
│
|
|
501
|
+
│ ├── media.ts # Image/file definitions
|
|
502
|
+
│ └── icons.ts # Icon definitions
|
|
404
503
|
├── .gitignore # Updated automatically
|
|
405
504
|
└── tsconfig.json # TypeScript config
|
|
406
505
|
```
|
|
@@ -458,7 +557,7 @@ uploadDefinitions(output)
|
|
|
458
557
|
### Built-in Processors
|
|
459
558
|
|
|
460
559
|
- **pathNormalizer** - Normalizes file paths across platforms
|
|
461
|
-
- **typeDetector** - Detects content, event, image, and
|
|
560
|
+
- **typeDetector** - Detects content, event, image, file, and icon types
|
|
462
561
|
- **duplicateValidator** - Prevents duplicate path definitions
|
|
463
562
|
- **metadataEnricher** - Adds processing metadata to output
|
|
464
563
|
|
|
@@ -510,6 +609,8 @@ tests/
|
|
|
510
609
|
│ ├── content-processor.test.ts # Content processing tests
|
|
511
610
|
│ ├── definition-processor.test.ts # Pipeline tests
|
|
512
611
|
│ ├── schema-processor.test.ts # TypeScript processing tests
|
|
612
|
+
│ ├── parallel-processing.test.ts # Parallel processing tests
|
|
613
|
+
│ ├── definitions-examples.test.ts # Example definition tests
|
|
513
614
|
│ └── integration.test.ts # End-to-end tests
|
|
514
615
|
├── definitions/
|
|
515
616
|
│ ├── someFile.ts # Basic test definitions
|
|
@@ -521,35 +622,17 @@ tests/
|
|
|
521
622
|
### Example Test
|
|
522
623
|
|
|
523
624
|
```typescript
|
|
524
|
-
describe("
|
|
525
|
-
it("should
|
|
625
|
+
describe("Icon Processing", () => {
|
|
626
|
+
it("should detect and process icon definitions", () => {
|
|
526
627
|
const contents: Content[] = [
|
|
527
628
|
{
|
|
528
|
-
path: "
|
|
529
|
-
structure: {
|
|
530
|
-
},
|
|
531
|
-
{
|
|
532
|
-
path: "page_view_event",
|
|
533
|
-
structure: {
|
|
534
|
-
type: "event",
|
|
535
|
-
properties: {
|
|
536
|
-
id: { const: "page_view" },
|
|
537
|
-
columns: { const: ["page", "user_id", "timestamp"] },
|
|
538
|
-
type: { const: "event" },
|
|
539
|
-
},
|
|
540
|
-
},
|
|
629
|
+
path: "/icons/menu",
|
|
630
|
+
structure: { __amatype: "AmaIconDef" },
|
|
541
631
|
},
|
|
542
632
|
];
|
|
543
633
|
|
|
544
|
-
const
|
|
545
|
-
|
|
546
|
-
expect(output.definitions["hero.json"]).toBeDefined();
|
|
547
|
-
expect(output.events["page_view"]).toBeDefined();
|
|
548
|
-
expect(output.events["page_view"]).toHaveProperty("columns", [
|
|
549
|
-
"page",
|
|
550
|
-
"user_id",
|
|
551
|
-
"timestamp",
|
|
552
|
-
]);
|
|
634
|
+
const contentType = determineContentType(contents[0]);
|
|
635
|
+
expect(contentType).toBe("icon");
|
|
553
636
|
});
|
|
554
637
|
});
|
|
555
638
|
```
|
|
@@ -561,13 +644,13 @@ describe("Event Processing", () => {
|
|
|
561
644
|
✅ **Do:**
|
|
562
645
|
|
|
563
646
|
- Group related definitions in separate files
|
|
564
|
-
- Use descriptive type names
|
|
647
|
+
- Use descriptive type names for icons (e.g., `MenuIcon`, `SearchIcon`)
|
|
565
648
|
- Keep event column order consistent
|
|
566
649
|
- Include comprehensive type documentation
|
|
567
650
|
|
|
568
651
|
❌ **Don't:**
|
|
569
652
|
|
|
570
|
-
- Mix content and
|
|
653
|
+
- Mix content, event, and media definitions unnecessarily
|
|
571
654
|
- Use dynamic or computed type names
|
|
572
655
|
- Ignore TypeScript compiler errors
|
|
573
656
|
|
|
@@ -15,6 +15,7 @@ const commander_1 = require("commander");
|
|
|
15
15
|
const utils_1 = require("../utils");
|
|
16
16
|
Object.defineProperty(exports, "registerTypeTransformer", { enumerable: true, get: function () { return utils_1.registerTypeTransformer; } });
|
|
17
17
|
Object.defineProperty(exports, "definitionPipeline", { enumerable: true, get: function () { return utils_1.definitionPipeline; } });
|
|
18
|
+
const parallel_schema_processor_1 = require("../utils/parallel-schema-processor");
|
|
18
19
|
// Main migrate command function
|
|
19
20
|
function migrateCommand() {
|
|
20
21
|
return new commander_1.Command("migrate")
|
|
@@ -23,22 +24,46 @@ function migrateCommand() {
|
|
|
23
24
|
.option("--verbose", "Enable verbose logging", false)
|
|
24
25
|
.option("--tsconfig <path>", "Path to tsconfig.json", "tsconfig.json")
|
|
25
26
|
.option("--continue-on-error", "Continue processing even if some files fail", false)
|
|
27
|
+
.option("--parallel", "Enable parallel processing using worker threads (default: true)", true)
|
|
28
|
+
.option("--max-workers <number>", "Maximum number of worker threads (default: CPU cores, max 8)", (value) => parseInt(value), undefined)
|
|
29
|
+
.option("--no-filtering", "Disable file pre-filtering optimization", false)
|
|
26
30
|
.action((options) => __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
const startTime = Date.now();
|
|
27
32
|
const logger = new utils_1.Logger(options.verbose);
|
|
28
33
|
try {
|
|
29
34
|
logger.info("🚀 Starting migration process");
|
|
30
35
|
logger.verbose_log(`Options: ${JSON.stringify(options)}`);
|
|
36
|
+
if (options.parallel) {
|
|
37
|
+
logger.info("⚡ Parallel processing enabled");
|
|
38
|
+
if (options.maxWorkers) {
|
|
39
|
+
logger.info(`👥 Using ${options.maxWorkers} worker threads`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
logger.info("🔄 Using sequential processing");
|
|
44
|
+
}
|
|
31
45
|
const config = (0, utils_1.getConfig)();
|
|
32
46
|
const patterns = config.include || ["**/*.ts", "**/*.tsx"];
|
|
33
47
|
// Create .ama directory if it doesn't exist
|
|
34
48
|
(0, utils_1.ensureAmaDirectory)(logger);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
49
|
+
let processingResult;
|
|
50
|
+
if (options.parallel !== false) {
|
|
51
|
+
// Use optimized parallel processing pipeline
|
|
52
|
+
logger.info("🚀 Using optimized parallel processing pipeline");
|
|
53
|
+
processingResult = yield (0, parallel_schema_processor_1.optimizedMigrationPipeline)(patterns, options.tsconfig, options.continueOnError, logger, options.maxWorkers);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// Fallback to original sequential processing
|
|
57
|
+
logger.info("🔄 Using original sequential processing");
|
|
58
|
+
const files = yield (0, utils_1.scanFiles)(patterns, logger);
|
|
59
|
+
logger.info(`📚 Found ${files.length} files to process`);
|
|
60
|
+
const project = (0, utils_1.createProject)(files, options.tsconfig, logger);
|
|
61
|
+
processingResult = (0, utils_1.processFiles)(project.getSourceFiles(), options.tsconfig, options.continueOnError, logger);
|
|
62
|
+
}
|
|
63
|
+
const { contents, errors, successCount, failureCount } = processingResult;
|
|
40
64
|
// Report processing results
|
|
41
|
-
|
|
65
|
+
const processingTime = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
66
|
+
logger.success(`✅ Successfully processed ${successCount} AMA contents in ${processingTime}s`);
|
|
42
67
|
if (failureCount > 0) {
|
|
43
68
|
logger.warn(`⚠️ Failed to process ${failureCount} items`);
|
|
44
69
|
if (options.verbose && errors.length > 0) {
|
|
@@ -51,25 +76,45 @@ function migrateCommand() {
|
|
|
51
76
|
process.exit(1);
|
|
52
77
|
}
|
|
53
78
|
// Generate and save output
|
|
79
|
+
const outputStartTime = Date.now();
|
|
80
|
+
logger.info("🔧 Generating output definitions...");
|
|
54
81
|
const output = (0, utils_1.generateOutput)(contents, config, logger);
|
|
82
|
+
const outputTime = ((Date.now() - outputStartTime) / 1000).toFixed(2);
|
|
83
|
+
logger.verbose_log(`Output generation took ${outputTime}s`);
|
|
55
84
|
(0, utils_1.saveOutputToFile)(output, logger);
|
|
56
85
|
// Upload definitions unless dry-run is enabled
|
|
57
86
|
if (!options.dryRun) {
|
|
58
|
-
logger.info("Uploading definitions to AtMyApp platform");
|
|
87
|
+
logger.info("📤 Uploading definitions to AtMyApp platform");
|
|
88
|
+
const uploadStartTime = Date.now();
|
|
59
89
|
const uploadSuccess = yield (0, utils_1.uploadDefinitions)(output, config, logger);
|
|
90
|
+
const uploadTime = ((Date.now() - uploadStartTime) / 1000).toFixed(2);
|
|
91
|
+
logger.verbose_log(`Upload took ${uploadTime}s`);
|
|
60
92
|
if (!uploadSuccess) {
|
|
61
93
|
logger.warn("Upload failed, but definitions were generated successfully");
|
|
62
94
|
process.exit(1);
|
|
63
95
|
}
|
|
64
96
|
}
|
|
65
97
|
else {
|
|
66
|
-
logger.info("Dry run mode enabled. Skipping upload to server.");
|
|
98
|
+
logger.info("🏁 Dry run mode enabled. Skipping upload to server.");
|
|
99
|
+
}
|
|
100
|
+
const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
101
|
+
logger.success(`🎉 Migration completed successfully in ${totalTime}s`);
|
|
102
|
+
// Performance summary
|
|
103
|
+
if (options.verbose) {
|
|
104
|
+
logger.info("📊 Performance Summary:");
|
|
105
|
+
logger.info(` Total time: ${totalTime}s`);
|
|
106
|
+
logger.info(` Processing time: ${processingTime}s`);
|
|
107
|
+
logger.info(` Files processed: ${successCount}`);
|
|
108
|
+
logger.info(` Processing mode: ${options.parallel !== false ? "Parallel" : "Sequential"}`);
|
|
109
|
+
if (options.parallel !== false && options.maxWorkers) {
|
|
110
|
+
logger.info(` Worker threads: ${options.maxWorkers}`);
|
|
111
|
+
}
|
|
67
112
|
}
|
|
68
|
-
logger.success("Migration completed successfully");
|
|
69
113
|
}
|
|
70
114
|
catch (error) {
|
|
115
|
+
const totalTime = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
71
116
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
72
|
-
logger.error(
|
|
117
|
+
logger.error(`💥 Fatal error after ${totalTime}s: ${message}`, error);
|
|
73
118
|
process.exit(1);
|
|
74
119
|
}
|
|
75
120
|
}));
|
|
@@ -15,21 +15,28 @@ function initializePipeline() {
|
|
|
15
15
|
}
|
|
16
16
|
// Determines the content type based on its structure and path
|
|
17
17
|
function determineContentType(content) {
|
|
18
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
18
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
19
19
|
// Extract file extension
|
|
20
20
|
const fileExt = (_a = content.path.split(".").pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
21
|
-
// Check for event types
|
|
21
|
+
// Check for event types - support both custom events and basic events
|
|
22
22
|
if (((_b = content.structure) === null || _b === void 0 ? void 0 : _b.type) === "event" ||
|
|
23
|
-
((
|
|
24
|
-
((_f = content.structure) === null || _f === void 0 ? void 0 : _f.
|
|
23
|
+
((_c = content.structure) === null || _c === void 0 ? void 0 : _c.type) === "basic_event" ||
|
|
24
|
+
((_f = (_e = (_d = content.structure) === null || _d === void 0 ? void 0 : _d.properties) === null || _e === void 0 ? void 0 : _e.type) === null || _f === void 0 ? void 0 : _f.const) === "event" ||
|
|
25
|
+
((_j = (_h = (_g = content.structure) === null || _g === void 0 ? void 0 : _g.properties) === null || _h === void 0 ? void 0 : _h.type) === null || _j === void 0 ? void 0 : _j.const) === "basic_event" ||
|
|
26
|
+
((_k = content.structure) === null || _k === void 0 ? void 0 : _k.__amatype) === "AmaCustomEventDef" ||
|
|
27
|
+
((_l = content.structure) === null || _l === void 0 ? void 0 : _l.__amatype) === "AmaEventDef") {
|
|
25
28
|
return "event";
|
|
26
29
|
}
|
|
30
|
+
// Check for icon types based on structure
|
|
31
|
+
if (((_m = content.structure) === null || _m === void 0 ? void 0 : _m.__amatype) === "AmaIconDef") {
|
|
32
|
+
return "icon";
|
|
33
|
+
}
|
|
27
34
|
// Check for image types based on structure or extension
|
|
28
|
-
if (((
|
|
35
|
+
if (((_o = content.structure) === null || _o === void 0 ? void 0 : _o.__amatype) === "AmaImageDef") {
|
|
29
36
|
return "image";
|
|
30
37
|
}
|
|
31
38
|
// Check for file types
|
|
32
|
-
if (((
|
|
39
|
+
if (((_p = content.structure) === null || _p === void 0 ? void 0 : _p.__amatype) === "AmaFileDef") {
|
|
33
40
|
return "file";
|
|
34
41
|
}
|
|
35
42
|
// Default type for other content
|
|
@@ -59,7 +66,9 @@ function extractEventConfig(content) {
|
|
|
59
66
|
else if ((_m = content.structure) === null || _m === void 0 ? void 0 : _m.id) {
|
|
60
67
|
eventId = content.structure.id;
|
|
61
68
|
}
|
|
62
|
-
|
|
69
|
+
// For basic events, columns might be empty (they use Record<string, string>)
|
|
70
|
+
// So we allow empty columns array for basic events
|
|
71
|
+
if (eventId) {
|
|
63
72
|
return { columns };
|
|
64
73
|
}
|
|
65
74
|
}
|
|
@@ -133,20 +133,23 @@ exports.builtInProcessors = {
|
|
|
133
133
|
typeDetector: {
|
|
134
134
|
name: "type-detector",
|
|
135
135
|
process: (content, context) => {
|
|
136
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
136
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
137
137
|
const { logger } = context;
|
|
138
138
|
// Extract file extension
|
|
139
139
|
const fileExt = (_a = content.path.split(".").pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
140
140
|
// Check for event types first
|
|
141
141
|
if (((_b = content.structure) === null || _b === void 0 ? void 0 : _b.type) === "event" ||
|
|
142
142
|
((_e = (_d = (_c = content.structure) === null || _c === void 0 ? void 0 : _c.properties) === null || _d === void 0 ? void 0 : _d.type) === null || _e === void 0 ? void 0 : _e.const) === "event" ||
|
|
143
|
-
((_f = content.structure) === null || _f === void 0 ? void 0 : _f.__amatype) === "
|
|
143
|
+
((_f = content.structure) === null || _f === void 0 ? void 0 : _f.__amatype) === "AmaCustomEventDef") {
|
|
144
144
|
content.type = "event";
|
|
145
145
|
}
|
|
146
|
-
else if (((_g = content.structure) === null || _g === void 0 ? void 0 : _g.__amatype) === "
|
|
146
|
+
else if (((_g = content.structure) === null || _g === void 0 ? void 0 : _g.__amatype) === "AmaIconDef") {
|
|
147
|
+
content.type = "icon";
|
|
148
|
+
}
|
|
149
|
+
else if (((_h = content.structure) === null || _h === void 0 ? void 0 : _h.__amatype) === "AmaImageDef") {
|
|
147
150
|
content.type = "image";
|
|
148
151
|
}
|
|
149
|
-
else if (((
|
|
152
|
+
else if (((_j = content.structure) === null || _j === void 0 ? void 0 : _j.__amatype) === "AmaFileDef") {
|
|
150
153
|
content.type = "file";
|
|
151
154
|
}
|
|
152
155
|
else if (["jpg", "jpeg", "png", "gif", "svg", "webp"].includes(fileExt || "")) {
|
|
@@ -5,5 +5,7 @@ export * from "./content-processor";
|
|
|
5
5
|
export * from "./file-operations";
|
|
6
6
|
export * from "./upload";
|
|
7
7
|
export * from "./definition-processor";
|
|
8
|
+
export * from "./parallel-schema-processor";
|
|
9
|
+
export * from "./worker-pool";
|
|
8
10
|
export * from "../types/migrate";
|
|
9
11
|
export * from "../logger";
|
package/dist/cli/utils/index.js
CHANGED
|
@@ -22,6 +22,8 @@ __exportStar(require("./content-processor"), exports);
|
|
|
22
22
|
__exportStar(require("./file-operations"), exports);
|
|
23
23
|
__exportStar(require("./upload"), exports);
|
|
24
24
|
__exportStar(require("./definition-processor"), exports);
|
|
25
|
+
__exportStar(require("./parallel-schema-processor"), exports);
|
|
26
|
+
__exportStar(require("./worker-pool"), exports);
|
|
25
27
|
// Re-export types and logger
|
|
26
28
|
__exportStar(require("../types/migrate"), exports);
|
|
27
29
|
__exportStar(require("../logger"), exports);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Logger } from "../logger";
|
|
2
|
+
import { ProcessingResult } from "../types/migrate";
|
|
3
|
+
export declare function scanFilesOptimized(patterns: string[], logger: Logger): Promise<string[]>;
|
|
4
|
+
export declare function processFilesParallel(files: string[], tsconfigPath: string, continueOnError: boolean, logger: Logger, maxWorkers?: number): Promise<ProcessingResult>;
|
|
5
|
+
export declare function optimizedMigrationPipeline(patterns: string[], tsconfigPath: string, continueOnError: boolean, logger: Logger, maxWorkers?: number): Promise<ProcessingResult>;
|