@tamyla/clodo-framework 4.0.13 → 4.0.14

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 (62) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +7 -0
  3. package/dist/cli/commands/create.js +2 -1
  4. package/dist/middleware/Composer.js +38 -0
  5. package/dist/middleware/Registry.js +14 -0
  6. package/dist/middleware/index.js +3 -0
  7. package/dist/middleware/shared/basicAuth.js +21 -0
  8. package/dist/middleware/shared/cors.js +28 -0
  9. package/dist/middleware/shared/index.js +3 -0
  10. package/dist/middleware/shared/logging.js +14 -0
  11. package/dist/service-management/GenerationEngine.js +13 -2
  12. package/dist/service-management/ServiceOrchestrator.js +6 -2
  13. package/dist/service-management/generators/code/ServiceMiddlewareGenerator.js +156 -10
  14. package/dist/service-management/generators/code/WorkerIndexGenerator.js +75 -9
  15. package/dist/simple-api.js +32 -1
  16. package/docs/MIDDLEWARE_MIGRATION_SUMMARY.md +121 -0
  17. package/package.json +4 -1
  18. package/scripts/DEPLOY_COMMAND_NEW.js +128 -0
  19. package/scripts/README-automated-testing-suite.md +356 -0
  20. package/scripts/README-test-clodo-deployment.md +157 -0
  21. package/scripts/README.md +50 -0
  22. package/scripts/analyze-imports.ps1 +104 -0
  23. package/scripts/analyze-mixed-code.js +163 -0
  24. package/scripts/analyze-mixed-rationale.js +149 -0
  25. package/scripts/automated-testing-suite.js +776 -0
  26. package/scripts/deployment/README.md +31 -0
  27. package/scripts/deployment/deploy-domain.ps1 +449 -0
  28. package/scripts/deployment/deploy-staging.js +120 -0
  29. package/scripts/deployment/validate-staging.js +166 -0
  30. package/scripts/diagnose-imports.js +362 -0
  31. package/scripts/framework-diagnostic.js +368 -0
  32. package/scripts/migration/migrate-middleware-legacy-to-contract.js +47 -0
  33. package/scripts/post-publish-test.js +663 -0
  34. package/scripts/scan-worker-issues.js +52 -0
  35. package/scripts/service-management/README.md +27 -0
  36. package/scripts/service-management/setup-interactive.ps1 +693 -0
  37. package/scripts/test-clodo-deployment.js +588 -0
  38. package/scripts/test-downstream-install.js +237 -0
  39. package/scripts/test-local-package.ps1 +126 -0
  40. package/scripts/test-local-package.sh +166 -0
  41. package/scripts/test-package.js +339 -0
  42. package/scripts/testing/README.md +49 -0
  43. package/scripts/testing/test-first.ps1 +0 -0
  44. package/scripts/testing/test-first50.ps1 +0 -0
  45. package/scripts/testing/test.ps1 +0 -0
  46. package/scripts/utilities/README.md +61 -0
  47. package/scripts/utilities/check-bin.js +8 -0
  48. package/scripts/utilities/check-bundle.js +23 -0
  49. package/scripts/utilities/check-dist-imports.js +65 -0
  50. package/scripts/utilities/check-import-paths.js +191 -0
  51. package/scripts/utilities/cleanup-cli.js +159 -0
  52. package/scripts/utilities/deployment-helpers.ps1 +199 -0
  53. package/scripts/utilities/fix-dist-imports.js +135 -0
  54. package/scripts/utilities/generate-secrets.js +159 -0
  55. package/scripts/utilities/safe-push.ps1 +51 -0
  56. package/scripts/utilities/setup-helpers.ps1 +206 -0
  57. package/scripts/utilities/test-packaged-artifact.js +92 -0
  58. package/scripts/utilities/validate-dist-imports.js +189 -0
  59. package/scripts/utilities/validate-schema.js +102 -0
  60. package/scripts/verify-exports.js +193 -0
  61. package/scripts/verify-worker-safety.js +73 -0
  62. package/types/middleware.d.ts +1 -0
@@ -0,0 +1,663 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Post-Publish Release Testing
4
+ *
5
+ * Comprehensive test that:
6
+ * 1. Creates a fresh test project in temp directory
7
+ * 2. Installs the published npm package
8
+ * 3. Tests all major exports and functionality
9
+ * 4. Validates CLI commands work
10
+ * 5. Tests worker integration
11
+ * 6. Verifies no import path errors
12
+ */
13
+
14
+ import { mkdtemp, rm, writeFile, mkdir } from 'fs/promises';
15
+ import { tmpdir } from 'os';
16
+ import { join } from 'path';
17
+ import { execSync } from 'child_process';
18
+
19
+ const PACKAGE_NAME = '@tamyla/clodo-framework';
20
+ const TEST_TIMEOUT = 120000; // 2 minutes
21
+
22
+ class PostPublishTester {
23
+ constructor() {
24
+ this.testDir = null;
25
+ this.results = {
26
+ passed: [],
27
+ failed: [],
28
+ skipped: []
29
+ };
30
+ }
31
+
32
+ log(message, type = 'info') {
33
+ const icons = { info: 'ℹ️', success: '✅', error: '❌', warning: '⚠️', test: '🧪' };
34
+ console.log(`${icons[type] || icons.info} ${message}`);
35
+ }
36
+
37
+ async setupTestEnvironment() {
38
+ this.log('Setting up test environment...', 'test');
39
+
40
+ // Create temporary directory
41
+ this.testDir = await mkdtemp(join(tmpdir(), 'clodo-release-test-'));
42
+ this.log(`Test directory: ${this.testDir}`);
43
+
44
+ // Create package.json
45
+ const packageJson = {
46
+ name: 'clodo-release-test',
47
+ version: '1.0.0',
48
+ type: 'module',
49
+ private: true
50
+ };
51
+
52
+ await writeFile(
53
+ join(this.testDir, 'package.json'),
54
+ JSON.stringify(packageJson, null, 2)
55
+ );
56
+
57
+ this.log('Test environment ready', 'success');
58
+ }
59
+
60
+ async installPublishedPackage() {
61
+ this.log(`Installing ${PACKAGE_NAME} from npm...`, 'test');
62
+
63
+ try {
64
+ execSync(`npm install ${PACKAGE_NAME}`, {
65
+ cwd: this.testDir,
66
+ stdio: 'pipe',
67
+ timeout: TEST_TIMEOUT
68
+ });
69
+
70
+ // Verify installation
71
+ const version = execSync(`npm list ${PACKAGE_NAME} --depth=0`, {
72
+ cwd: this.testDir,
73
+ encoding: 'utf8'
74
+ });
75
+
76
+ this.log(`Installed: ${version.trim()}`, 'success');
77
+ this.results.passed.push('Package installation');
78
+ return true;
79
+ } catch (error) {
80
+ this.log(`Installation failed: ${error.message}`, 'error');
81
+ this.results.failed.push(`Package installation: ${error.message}`);
82
+ return false;
83
+ }
84
+ }
85
+
86
+ async testMainExports() {
87
+ this.log('Testing main exports...', 'test');
88
+
89
+ const testFile = join(this.testDir, 'test-exports.mjs');
90
+ const testCode = `
91
+ import {
92
+ Clodo,
93
+ createService,
94
+ validate,
95
+ initialize,
96
+ GenericDataService,
97
+ SchemaManager,
98
+ ModuleManager,
99
+ EnhancedRouter,
100
+ createDomainConfigSchema,
101
+ validateDomainConfig,
102
+ SecurityCLI,
103
+ DeploymentValidator,
104
+ DeploymentAuditor,
105
+ StandardOptions,
106
+ OutputFormatter
107
+ } from '${PACKAGE_NAME}';
108
+
109
+ // Test that exports are defined
110
+ const exports = {
111
+ Clodo,
112
+ createService,
113
+ validate,
114
+ initialize,
115
+ GenericDataService,
116
+ SchemaManager,
117
+ ModuleManager,
118
+ EnhancedRouter,
119
+ createDomainConfigSchema,
120
+ validateDomainConfig,
121
+ SecurityCLI,
122
+ DeploymentValidator,
123
+ DeploymentAuditor,
124
+ StandardOptions,
125
+ OutputFormatter
126
+ };
127
+
128
+ let passed = 0;
129
+ let failed = 0;
130
+
131
+ for (const [name, value] of Object.entries(exports)) {
132
+ if (value !== undefined && value !== null) {
133
+ console.log(\`✅ \${name}\`);
134
+ passed++;
135
+ } else {
136
+ console.log(\`❌ \${name} is undefined\`);
137
+ failed++;
138
+ }
139
+ }
140
+
141
+ console.log(\`\\nResults: \${passed} passed, \${failed} failed\`);
142
+ process.exit(failed > 0 ? 1 : 0);
143
+ `;
144
+
145
+ await writeFile(testFile, testCode);
146
+
147
+ try {
148
+ const output = execSync(`node ${testFile}`, {
149
+ cwd: this.testDir,
150
+ encoding: 'utf8',
151
+ timeout: 30000
152
+ });
153
+
154
+ this.log('Main exports test results:', 'info');
155
+ console.log(output);
156
+ this.results.passed.push('Main exports');
157
+ return true;
158
+ } catch (error) {
159
+ this.log(`Main exports test failed: ${error.message}`, 'error');
160
+ if (error.stdout) console.log(error.stdout.toString());
161
+ this.results.failed.push(`Main exports: ${error.message}`);
162
+ return false;
163
+ }
164
+ }
165
+
166
+ async testWorkerIntegration() {
167
+ this.log('Testing worker integration...', 'test');
168
+
169
+ const testFile = join(this.testDir, 'test-worker.mjs');
170
+ const testCode = `
171
+ import { initializeService, createFeatureGuard, createRateLimitGuard } from '${PACKAGE_NAME}/worker';
172
+
173
+ try {
174
+ // Test that worker functions are available
175
+ console.log('✅ initializeService:', typeof initializeService);
176
+ console.log('✅ createFeatureGuard:', typeof createFeatureGuard);
177
+ console.log('✅ createRateLimitGuard:', typeof createRateLimitGuard);
178
+
179
+ // Test basic feature guard creation
180
+ const guard = createFeatureGuard('TEST_FEATURE');
181
+ console.log('✅ Created feature guard successfully');
182
+
183
+ // Test rate limit guard creation
184
+ const rateLimit = createRateLimitGuard({ maxRequests: 100, windowMs: 60000 });
185
+ console.log('✅ Created rate limit guard successfully');
186
+
187
+ console.log('\\n✅ Worker integration test passed');
188
+ process.exit(0);
189
+ } catch (error) {
190
+ console.error('❌ Worker integration test failed:', error.message);
191
+ process.exit(1);
192
+ }
193
+ `;
194
+
195
+ await writeFile(testFile, testCode);
196
+
197
+ try {
198
+ const output = execSync(`node ${testFile}`, {
199
+ cwd: this.testDir,
200
+ encoding: 'utf8',
201
+ timeout: 30000
202
+ });
203
+
204
+ console.log(output);
205
+ this.results.passed.push('Worker integration');
206
+ return true;
207
+ } catch (error) {
208
+ this.log(`Worker integration test failed: ${error.message}`, 'error');
209
+ if (error.stdout) console.log(error.stdout.toString());
210
+ this.results.failed.push(`Worker integration: ${error.message}`);
211
+ return false;
212
+ }
213
+ }
214
+
215
+ async testCLICommands() {
216
+ this.log('Testing CLI commands...', 'test');
217
+
218
+ const commands = [
219
+ { name: 'version', cmd: 'clodo-service --version', expect: /\d+\.\d+\.\d+/ },
220
+ { name: 'help', cmd: 'clodo-service --help', expect: /(Usage|Commands)/ },
221
+ { name: 'create help', cmd: 'clodo-service create --help', expect: /Create.*service/ },
222
+ { name: 'validate help', cmd: 'clodo-service validate --help', expect: /Validate.*service/ },
223
+ { name: 'deploy help', cmd: 'clodo-service deploy --help', expect: /Deploy.*service/ },
224
+ { name: 'init-config help', cmd: 'clodo-service init-config --help', expect: /Initialize.*config/ },
225
+ ];
226
+
227
+ let passed = 0;
228
+ let failed = 0;
229
+
230
+ for (const { name, cmd, expect } of commands) {
231
+ try {
232
+ const output = execSync(`npx ${cmd}`, {
233
+ cwd: this.testDir,
234
+ encoding: 'utf8',
235
+ timeout: 10000
236
+ });
237
+
238
+ if (expect.test(output)) {
239
+ this.log(` ✓ ${name}`, 'success');
240
+ passed++;
241
+ } else {
242
+ this.log(` ✗ ${name} - unexpected output`, 'error');
243
+ failed++;
244
+ }
245
+ } catch (error) {
246
+ this.log(` ✗ ${name} - ${error.message}`, 'error');
247
+ failed++;
248
+ }
249
+ }
250
+
251
+ if (failed === 0) {
252
+ this.log(`All ${passed} CLI commands working`, 'success');
253
+ this.results.passed.push(`CLI commands (${passed}/${commands.length})`);
254
+ return true;
255
+ } else {
256
+ this.log(`${failed} CLI commands failed`, 'error');
257
+ this.results.failed.push(`CLI commands: ${failed}/${commands.length} failed`);
258
+ return false;
259
+ }
260
+ }
261
+
262
+ async testServiceCreation() {
263
+ this.log('Testing service creation API...', 'test');
264
+
265
+ const testFile = join(this.testDir, 'test-service-api.mjs');
266
+ const testCode = `
267
+ import { Clodo } from '${PACKAGE_NAME}';
268
+
269
+ try {
270
+ // Test that Clodo API exists
271
+ console.log('✅ Clodo.createService:', typeof Clodo.createService);
272
+ console.log('✅ Clodo.validate:', typeof Clodo.validate);
273
+ console.log('✅ Clodo.deploy:', typeof Clodo.deploy);
274
+ console.log('✅ Clodo.initialize:', typeof Clodo.initialize);
275
+ console.log('✅ Clodo.getInfo:', typeof Clodo.getInfo);
276
+
277
+ // Test getInfo
278
+ const info = Clodo.getInfo();
279
+ console.log('✅ Framework info:', info.name);
280
+
281
+ if (info.name !== 'Clodo Framework') {
282
+ throw new Error('Framework info incorrect');
283
+ }
284
+
285
+ console.log('\\n✅ Service creation API test passed');
286
+ process.exit(0);
287
+ } catch (error) {
288
+ console.error('❌ Service API test failed:', error.message);
289
+ process.exit(1);
290
+ }
291
+ `;
292
+
293
+ await writeFile(testFile, testCode);
294
+
295
+ try {
296
+ const output = execSync(`node ${testFile}`, {
297
+ cwd: this.testDir,
298
+ encoding: 'utf8',
299
+ timeout: 30000
300
+ });
301
+
302
+ console.log(output);
303
+ this.results.passed.push('Service creation API');
304
+ return true;
305
+ } catch (error) {
306
+ this.log(`Service API test failed: ${error.message}`, 'error');
307
+ if (error.stdout) console.log(error.stdout.toString());
308
+ this.results.failed.push(`Service creation API: ${error.message}`);
309
+ return false;
310
+ }
311
+ }
312
+
313
+ async testConfigurationManagement() {
314
+ this.log('Testing configuration management...', 'test');
315
+
316
+ const testFile = join(this.testDir, 'test-config.mjs');
317
+ const testCode = `
318
+ import { StandardOptions, OutputFormatter } from '${PACKAGE_NAME}';
319
+
320
+ try {
321
+ console.log('✅ StandardOptions:', typeof StandardOptions);
322
+ console.log('✅ OutputFormatter:', typeof OutputFormatter);
323
+
324
+ // Test StandardOptions has required methods
325
+ if (typeof StandardOptions.define !== 'function') {
326
+ throw new Error('StandardOptions.define is not a function');
327
+ }
328
+ console.log('✅ StandardOptions.define exists');
329
+
330
+ // Test OutputFormatter can be instantiated
331
+ const formatter = new OutputFormatter({});
332
+ console.log('✅ OutputFormatter instance created');
333
+
334
+ console.log('\\n✅ Configuration management test passed');
335
+ process.exit(0);
336
+ } catch (error) {
337
+ console.error('❌ Configuration test failed:', error.message);
338
+ process.exit(1);
339
+ }
340
+ `;
341
+
342
+ await writeFile(testFile, testCode);
343
+
344
+ try {
345
+ const output = execSync(`node ${testFile}`, {
346
+ cwd: this.testDir,
347
+ encoding: 'utf8',
348
+ timeout: 30000
349
+ });
350
+
351
+ console.log(output);
352
+ this.results.passed.push('Configuration management');
353
+ return true;
354
+ } catch (error) {
355
+ this.log(`Configuration test failed: ${error.message}`, 'error');
356
+ if (error.stdout) console.log(error.stdout.toString());
357
+ this.results.failed.push(`Configuration management: ${error.message}`);
358
+ return false;
359
+ }
360
+ }
361
+
362
+ async testSecurityFeatures() {
363
+ this.log('Testing security features...', 'test');
364
+
365
+ const testFile = join(this.testDir, 'test-security.mjs');
366
+ const testCode = `
367
+ import { SecurityCLI } from '${PACKAGE_NAME}';
368
+
369
+ try {
370
+ console.log('✅ SecurityCLI:', typeof SecurityCLI);
371
+
372
+ // Verify SecurityCLI has expected methods
373
+ const securityCli = new SecurityCLI();
374
+ console.log('✅ SecurityCLI instance created');
375
+
376
+ console.log('\\n✅ Security features test passed');
377
+ process.exit(0);
378
+ } catch (error) {
379
+ console.error('❌ Security test failed:', error.message);
380
+ process.exit(1);
381
+ }
382
+ `;
383
+
384
+ await writeFile(testFile, testCode);
385
+
386
+ try {
387
+ const output = execSync(`node ${testFile}`, {
388
+ cwd: this.testDir,
389
+ encoding: 'utf8',
390
+ timeout: 30000
391
+ });
392
+
393
+ console.log(output);
394
+ this.results.passed.push('Security features');
395
+ return true;
396
+ } catch (error) {
397
+ this.log(`Security test failed: ${error.message}`, 'error');
398
+ if (error.stdout) console.log(error.stdout.toString());
399
+ this.results.failed.push(`Security features: ${error.message}`);
400
+ return false;
401
+ }
402
+ }
403
+
404
+ async testInheritableCapabilities() {
405
+ this.log('Testing inheritable classes and capabilities...', 'test');
406
+
407
+ const testFile = join(this.testDir, 'test-inheritance.mjs');
408
+ const testCode = `
409
+ import {
410
+ SchemaManager,
411
+ ModuleManager,
412
+ EnhancedRouter
413
+ } from '${PACKAGE_NAME}';
414
+
415
+ try {
416
+ let passed = 0;
417
+ let failed = 0;
418
+
419
+ // Note: GenericDataService requires D1 database client and is designed
420
+ // for runtime use with Cloudflare Workers, not standalone inheritance testing
421
+
422
+ // Test SchemaManager extensibility
423
+ try {
424
+ class CustomSchemaManager extends SchemaManager {
425
+ constructor() {
426
+ super();
427
+ }
428
+
429
+ customMethod() {
430
+ return 'custom';
431
+ }
432
+ }
433
+ const customSchema = new CustomSchemaManager();
434
+ if (customSchema.customMethod() === 'custom') {
435
+ console.log('✅ SchemaManager - extendable with custom methods');
436
+ passed++;
437
+ } else {
438
+ throw new Error('Custom method not working');
439
+ }
440
+ } catch (e) {
441
+ console.log('❌ SchemaManager - not extendable:', e.message);
442
+ failed++;
443
+ }
444
+
445
+ // Test ModuleManager extensibility
446
+ try {
447
+ class CustomModuleManager extends ModuleManager {
448
+ constructor() {
449
+ super();
450
+ }
451
+
452
+ customRegister(name) {
453
+ return \`custom-\${name}\`;
454
+ }
455
+ }
456
+ const customModule = new CustomModuleManager();
457
+ if (customModule.customRegister('test') === 'custom-test') {
458
+ console.log('✅ ModuleManager - extendable with custom methods');
459
+ passed++;
460
+ } else {
461
+ throw new Error('Custom method not working');
462
+ }
463
+ } catch (e) {
464
+ console.log('❌ ModuleManager - not extendable:', e.message);
465
+ failed++;
466
+ }
467
+
468
+ // Test EnhancedRouter extensibility
469
+ try {
470
+ class CustomRouter extends EnhancedRouter {
471
+ constructor() {
472
+ super();
473
+ }
474
+
475
+ customRoute(path) {
476
+ return \`/custom\${path}\`;
477
+ }
478
+ }
479
+ const customRouter = new CustomRouter();
480
+ if (customRouter.customRoute('/test') === '/custom/test') {
481
+ console.log('✅ EnhancedRouter - extendable with custom methods');
482
+ passed++;
483
+ } else {
484
+ throw new Error('Custom method not working');
485
+ }
486
+ } catch (e) {
487
+ console.log('❌ EnhancedRouter - not extendable:', e.message);
488
+ failed++;
489
+ }
490
+
491
+ console.log(\`\\nResults: \${passed} passed, \${failed} failed\`);
492
+ console.log('Note: GenericDataService requires D1 client and is tested in worker integration');
493
+ process.exit(failed > 0 ? 1 : 0);
494
+ } catch (error) {
495
+ console.error('❌ Inheritance test failed:', error.message);
496
+ process.exit(1);
497
+ }
498
+ `;
499
+
500
+ await writeFile(testFile, testCode);
501
+
502
+ try {
503
+ const output = execSync(`node ${testFile}`, {
504
+ cwd: this.testDir,
505
+ encoding: 'utf8',
506
+ timeout: 30000
507
+ });
508
+
509
+ console.log(output);
510
+ this.results.passed.push('Inheritable capabilities');
511
+ return true;
512
+ } catch (error) {
513
+ this.log(`Inheritance test failed: ${error.message}`, 'error');
514
+ if (error.stdout) console.log(error.stdout.toString());
515
+ this.results.failed.push(`Inheritable capabilities: ${error.message}`);
516
+ return false;
517
+ }
518
+ }
519
+
520
+ async testDeploymentCapabilities() {
521
+ this.log('Testing deployment and orchestration...', 'test');
522
+
523
+ const testFile = join(this.testDir, 'test-deployment.mjs');
524
+ const testCode = `
525
+ import {
526
+ DeploymentValidator,
527
+ DeploymentAuditor
528
+ } from '${PACKAGE_NAME}';
529
+
530
+ try {
531
+ console.log('✅ DeploymentValidator:', typeof DeploymentValidator);
532
+ console.log('✅ DeploymentAuditor:', typeof DeploymentAuditor);
533
+
534
+ // Test that validators can be instantiated
535
+ const validator = new DeploymentValidator();
536
+ console.log('✅ DeploymentValidator instance created');
537
+
538
+ const auditor = new DeploymentAuditor();
539
+ console.log('✅ DeploymentAuditor instance created');
540
+
541
+ console.log('\\n✅ Deployment capabilities test passed');
542
+ process.exit(0);
543
+ } catch (error) {
544
+ console.error('❌ Deployment test failed:', error.message);
545
+ process.exit(1);
546
+ }
547
+ `;
548
+
549
+ await writeFile(testFile, testCode);
550
+
551
+ try {
552
+ const output = execSync(`node ${testFile}`, {
553
+ cwd: this.testDir,
554
+ encoding: 'utf8',
555
+ timeout: 30000
556
+ });
557
+
558
+ console.log(output);
559
+ this.results.passed.push('Deployment capabilities');
560
+ return true;
561
+ } catch (error) {
562
+ this.log(`Deployment test failed: ${error.message}`, 'error');
563
+ if (error.stdout) console.log(error.stdout.toString());
564
+ this.results.failed.push(`Deployment capabilities: ${error.message}`);
565
+ return false;
566
+ }
567
+ }
568
+
569
+ async cleanup() {
570
+ if (this.testDir) {
571
+ this.log('Cleaning up test environment...', 'info');
572
+ try {
573
+ await rm(this.testDir, { recursive: true, force: true });
574
+ this.log('Cleanup complete', 'success');
575
+ } catch (error) {
576
+ this.log(`Cleanup warning: ${error.message}`, 'warning');
577
+ }
578
+ }
579
+ }
580
+
581
+ printSummary() {
582
+ console.log('\n' + '='.repeat(60));
583
+ console.log('📊 POST-PUBLISH TEST SUMMARY');
584
+ console.log('='.repeat(60));
585
+
586
+ if (this.results.passed.length > 0) {
587
+ console.log(`\n✅ PASSED (${this.results.passed.length}):`);
588
+ this.results.passed.forEach(test => console.log(` ✓ ${test}`));
589
+ }
590
+
591
+ if (this.results.failed.length > 0) {
592
+ console.log(`\n❌ FAILED (${this.results.failed.length}):`);
593
+ this.results.failed.forEach(test => console.log(` ✗ ${test}`));
594
+ }
595
+
596
+ if (this.results.skipped.length > 0) {
597
+ console.log(`\n⏭️ SKIPPED (${this.results.skipped.length}):`);
598
+ this.results.skipped.forEach(test => console.log(` - ${test}`));
599
+ }
600
+
601
+ const total = this.results.passed.length + this.results.failed.length;
602
+ const successRate = total > 0 ? ((this.results.passed.length / total) * 100).toFixed(1) : 0;
603
+
604
+ console.log('\n' + '='.repeat(60));
605
+ console.log(`Total: ${total} tests | Success Rate: ${successRate}%`);
606
+ console.log('='.repeat(60));
607
+
608
+ if (this.results.failed.length === 0) {
609
+ console.log('\n🎉 All post-publish tests passed!');
610
+ console.log('✅ Package is ready for production use');
611
+ return true;
612
+ } else {
613
+ console.log('\n⚠️ Some tests failed. Review the failures above.');
614
+ return false;
615
+ }
616
+ }
617
+
618
+ async run() {
619
+ console.log('╔═══════════════════════════════════════════════════════════╗');
620
+ console.log('║ POST-PUBLISH RELEASE TESTING ║');
621
+ console.log('║ Testing published package from npm registry ║');
622
+ console.log('╚═══════════════════════════════════════════════════════════╝\n');
623
+
624
+ try {
625
+ await this.setupTestEnvironment();
626
+
627
+ const installed = await this.installPublishedPackage();
628
+ if (!installed) {
629
+ this.log('Cannot proceed without successful installation', 'error');
630
+ return false;
631
+ }
632
+
633
+ // Run all tests
634
+ await this.testMainExports();
635
+ await this.testWorkerIntegration();
636
+ await this.testCLICommands();
637
+ await this.testServiceCreation();
638
+ await this.testConfigurationManagement();
639
+ await this.testSecurityFeatures();
640
+ await this.testInheritableCapabilities();
641
+ await this.testDeploymentCapabilities();
642
+
643
+ const success = this.printSummary();
644
+ return success;
645
+
646
+ } catch (error) {
647
+ this.log(`Unexpected error: ${error.message}`, 'error');
648
+ console.error(error);
649
+ return false;
650
+ } finally {
651
+ await this.cleanup();
652
+ }
653
+ }
654
+ }
655
+
656
+ // Run the tests
657
+ const tester = new PostPublishTester();
658
+ tester.run().then(success => {
659
+ process.exit(success ? 0 : 1);
660
+ }).catch(error => {
661
+ console.error('Fatal error:', error);
662
+ process.exit(1);
663
+ });
@@ -0,0 +1,52 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+
8
+ const incompatiblePatterns = [
9
+ /import.*from.*['"]fs['"]/,
10
+ /import.*from.*['"]path['"]/,
11
+ /import.*from.*['"]child_process['"]/,
12
+ /import.*from.*['"]os['"]/,
13
+ /import.*from.*['"]https['"]/,
14
+ /import.*from.*['"]http['"]/,
15
+ /process\.cwd/,
16
+ /__dirname/,
17
+ /__filename/,
18
+ /readFileSync|writeFileSync|existsSync|mkdirSync|readdirSync|statSync/
19
+ ];
20
+
21
+ function scanDirectory(dir, results = []) {
22
+ try {
23
+ const items = fs.readdirSync(dir);
24
+ for (const item of items) {
25
+ const fullPath = path.join(dir, item);
26
+ const stat = fs.statSync(fullPath);
27
+ if (stat.isDirectory() && !item.startsWith('.') && item !== 'node_modules') {
28
+ scanDirectory(fullPath, results);
29
+ } else if (item.endsWith('.js')) {
30
+ const content = fs.readFileSync(fullPath, 'utf8');
31
+ const issues = [];
32
+ for (const pattern of incompatiblePatterns) {
33
+ const matches = content.match(pattern);
34
+ if (matches) {
35
+ issues.push(matches[0]);
36
+ }
37
+ }
38
+ if (issues.length > 0) {
39
+ results.push({ file: fullPath, issues });
40
+ }
41
+ }
42
+ }
43
+ } catch (e) {}
44
+ return results;
45
+ }
46
+
47
+ const results = scanDirectory('src');
48
+ console.log('Files with Worker-incompatible code:');
49
+ results.forEach(r => {
50
+ console.log(`\n${r.file}:`);
51
+ r.issues.forEach(issue => console.log(` - ${issue}`));
52
+ });