canxjs 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/cli/bin.ts +193 -0
  2. package/dist/src/auth/EmailVerification.d.ts +75 -0
  3. package/dist/src/auth/EmailVerification.d.ts.map +1 -0
  4. package/dist/src/auth/EmailVerification.js +151 -0
  5. package/dist/src/auth/OAuth.d.ts +64 -0
  6. package/dist/src/auth/OAuth.d.ts.map +1 -0
  7. package/dist/src/auth/OAuth.js +245 -0
  8. package/dist/src/auth/RefreshToken.d.ts +82 -0
  9. package/dist/src/auth/RefreshToken.d.ts.map +1 -0
  10. package/dist/src/auth/RefreshToken.js +174 -0
  11. package/dist/src/auth/TwoFactor.d.ts +60 -0
  12. package/dist/src/auth/TwoFactor.d.ts.map +1 -0
  13. package/dist/src/auth/TwoFactor.js +179 -0
  14. package/dist/src/cache/TaggedCache.d.ts +133 -0
  15. package/dist/src/cache/TaggedCache.d.ts.map +1 -0
  16. package/dist/src/cache/TaggedCache.js +271 -0
  17. package/dist/src/cli/commands/Dashboard.d.ts +7 -0
  18. package/dist/src/cli/commands/Dashboard.d.ts.map +1 -0
  19. package/dist/src/cli/commands/Dashboard.js +54 -0
  20. package/dist/src/cli/index.d.ts.map +1 -1
  21. package/dist/src/cli/index.js +2 -0
  22. package/dist/src/config/ConfigManager.d.ts +62 -0
  23. package/dist/src/config/ConfigManager.d.ts.map +1 -0
  24. package/dist/src/config/ConfigManager.js +187 -0
  25. package/dist/src/container/Container.d.ts +34 -5
  26. package/dist/src/container/Container.d.ts.map +1 -1
  27. package/dist/src/container/Container.js +74 -9
  28. package/dist/src/container/Scope.d.ts +91 -0
  29. package/dist/src/container/Scope.d.ts.map +1 -0
  30. package/dist/src/container/Scope.js +179 -0
  31. package/dist/src/core/AOP.d.ts +89 -0
  32. package/dist/src/core/AOP.d.ts.map +1 -0
  33. package/dist/src/core/AOP.js +218 -0
  34. package/dist/src/core/Application.d.ts +53 -0
  35. package/dist/src/core/Application.d.ts.map +1 -0
  36. package/dist/src/core/Application.js +172 -0
  37. package/dist/src/core/Decorators.d.ts +178 -0
  38. package/dist/src/core/Decorators.d.ts.map +1 -0
  39. package/dist/src/core/Decorators.js +403 -0
  40. package/dist/src/core/Http2Server.d.ts +101 -0
  41. package/dist/src/core/Http2Server.d.ts.map +1 -0
  42. package/dist/src/core/Http2Server.js +380 -0
  43. package/dist/src/core/Lifecycle.d.ts +41 -0
  44. package/dist/src/core/Lifecycle.d.ts.map +1 -0
  45. package/dist/src/core/Lifecycle.js +5 -0
  46. package/dist/src/core/Module.d.ts +214 -0
  47. package/dist/src/core/Module.d.ts.map +1 -0
  48. package/dist/src/core/Module.js +492 -0
  49. package/dist/src/core/Router.d.ts +4 -0
  50. package/dist/src/core/Router.d.ts.map +1 -1
  51. package/dist/src/core/Router.js +30 -10
  52. package/dist/src/core/Server.d.ts.map +1 -1
  53. package/dist/src/core/Server.js +2 -0
  54. package/dist/src/core/ServiceProvider.d.ts +60 -0
  55. package/dist/src/core/ServiceProvider.d.ts.map +1 -0
  56. package/dist/src/core/ServiceProvider.js +91 -0
  57. package/dist/src/core/Tracing.d.ts +12 -0
  58. package/dist/src/core/Tracing.d.ts.map +1 -0
  59. package/dist/src/core/Tracing.js +63 -0
  60. package/dist/src/core/exceptions/CanxException.d.ts +2 -0
  61. package/dist/src/core/exceptions/CanxException.d.ts.map +1 -1
  62. package/dist/src/core/exceptions/CanxException.js +5 -0
  63. package/dist/src/core/exceptions/ConflictException.d.ts +1 -1
  64. package/dist/src/core/exceptions/ConflictException.d.ts.map +1 -1
  65. package/dist/src/core/exceptions/ConflictException.js +3 -2
  66. package/dist/src/core/exceptions/NotFoundException.d.ts +1 -1
  67. package/dist/src/core/exceptions/NotFoundException.d.ts.map +1 -1
  68. package/dist/src/core/exceptions/NotFoundException.js +3 -1
  69. package/dist/src/core/exceptions/ServiceUnavailableException.d.ts +1 -1
  70. package/dist/src/core/exceptions/ServiceUnavailableException.d.ts.map +1 -1
  71. package/dist/src/core/exceptions/ServiceUnavailableException.js +3 -3
  72. package/dist/src/core/exceptions/ValidationException.d.ts +6 -2
  73. package/dist/src/core/exceptions/ValidationException.d.ts.map +1 -1
  74. package/dist/src/core/exceptions/ValidationException.js +9 -2
  75. package/dist/src/cqrs/CqrsModule.d.ts +202 -0
  76. package/dist/src/cqrs/CqrsModule.d.ts.map +1 -0
  77. package/dist/src/cqrs/CqrsModule.js +387 -0
  78. package/dist/src/cqrs/EventSourcing.d.ts +205 -0
  79. package/dist/src/cqrs/EventSourcing.d.ts.map +1 -0
  80. package/dist/src/cqrs/EventSourcing.js +397 -0
  81. package/dist/src/cqrs/index.d.ts +9 -0
  82. package/dist/src/cqrs/index.d.ts.map +1 -0
  83. package/dist/src/cqrs/index.js +20 -0
  84. package/dist/src/database/Factory.d.ts +32 -0
  85. package/dist/src/database/Factory.d.ts.map +1 -0
  86. package/dist/src/database/Factory.js +107 -0
  87. package/dist/src/devtools/DevToolsModule.d.ts +25 -0
  88. package/dist/src/devtools/DevToolsModule.d.ts.map +1 -0
  89. package/dist/src/devtools/DevToolsModule.js +76 -0
  90. package/dist/src/features/AsyncApi.d.ts +48 -0
  91. package/dist/src/features/AsyncApi.d.ts.map +1 -0
  92. package/dist/src/features/AsyncApi.js +52 -0
  93. package/dist/src/generator/ClientGenerator.d.ts.map +1 -1
  94. package/dist/src/generator/ClientGenerator.js +36 -13
  95. package/dist/src/generator/OpenAPIGenerator.d.ts +171 -0
  96. package/dist/src/generator/OpenAPIGenerator.d.ts.map +1 -0
  97. package/dist/src/generator/OpenAPIGenerator.js +287 -0
  98. package/dist/src/graphql/CodeFirst.d.ts +192 -0
  99. package/dist/src/graphql/CodeFirst.d.ts.map +1 -0
  100. package/dist/src/graphql/CodeFirst.js +539 -0
  101. package/dist/src/graphql/Federation.d.ts +104 -0
  102. package/dist/src/graphql/Federation.d.ts.map +1 -0
  103. package/dist/src/graphql/Federation.js +297 -0
  104. package/dist/src/graphql/GraphQLAdapter.d.ts +50 -0
  105. package/dist/src/graphql/GraphQLAdapter.d.ts.map +1 -0
  106. package/dist/src/graphql/GraphQLAdapter.js +221 -0
  107. package/dist/src/graphql/SchemaFirst.d.ts +91 -0
  108. package/dist/src/graphql/SchemaFirst.d.ts.map +1 -0
  109. package/dist/src/graphql/SchemaFirst.js +206 -0
  110. package/dist/src/graphql/index.d.ts +13 -0
  111. package/dist/src/graphql/index.d.ts.map +1 -0
  112. package/dist/src/graphql/index.js +36 -0
  113. package/dist/src/health/HealthModule.d.ts +60 -0
  114. package/dist/src/health/HealthModule.d.ts.map +1 -0
  115. package/dist/src/health/HealthModule.js +175 -0
  116. package/dist/src/index.d.ts +74 -11
  117. package/dist/src/index.d.ts.map +1 -1
  118. package/dist/src/index.js +141 -10
  119. package/dist/src/microservices/Broker.d.ts +126 -0
  120. package/dist/src/microservices/Broker.d.ts.map +1 -0
  121. package/dist/src/microservices/Broker.js +307 -0
  122. package/dist/src/microservices/Transport.d.ts +171 -0
  123. package/dist/src/microservices/Transport.d.ts.map +1 -0
  124. package/dist/src/microservices/Transport.js +314 -0
  125. package/dist/src/microservices/transports/GrpcTransport.d.ts +78 -0
  126. package/dist/src/microservices/transports/GrpcTransport.d.ts.map +1 -0
  127. package/dist/src/microservices/transports/GrpcTransport.js +252 -0
  128. package/dist/src/microservices/transports/KafkaTransport.d.ts +62 -0
  129. package/dist/src/microservices/transports/KafkaTransport.d.ts.map +1 -0
  130. package/dist/src/microservices/transports/KafkaTransport.js +271 -0
  131. package/dist/src/microservices/transports/MqttTransport.d.ts +62 -0
  132. package/dist/src/microservices/transports/MqttTransport.d.ts.map +1 -0
  133. package/dist/src/microservices/transports/MqttTransport.js +243 -0
  134. package/dist/src/microservices/transports/NatsTransport.d.ts +46 -0
  135. package/dist/src/microservices/transports/NatsTransport.d.ts.map +1 -0
  136. package/dist/src/microservices/transports/NatsTransport.js +188 -0
  137. package/dist/src/microservices/transports/RedisTransport.d.ts +58 -0
  138. package/dist/src/microservices/transports/RedisTransport.d.ts.map +1 -0
  139. package/dist/src/microservices/transports/RedisTransport.js +208 -0
  140. package/dist/src/microservices/transports/index.d.ts +18 -0
  141. package/dist/src/microservices/transports/index.d.ts.map +1 -0
  142. package/dist/src/microservices/transports/index.js +24 -0
  143. package/dist/src/middlewares/HelmetMiddleware.d.ts +49 -0
  144. package/dist/src/middlewares/HelmetMiddleware.d.ts.map +1 -0
  145. package/dist/src/middlewares/HelmetMiddleware.js +177 -0
  146. package/dist/src/middlewares/RateLimiter.d.ts +88 -0
  147. package/dist/src/middlewares/RateLimiter.d.ts.map +1 -0
  148. package/dist/src/middlewares/RateLimiter.js +204 -0
  149. package/dist/src/middlewares/SanitizeMiddleware.d.ts +50 -0
  150. package/dist/src/middlewares/SanitizeMiddleware.d.ts.map +1 -0
  151. package/dist/src/middlewares/SanitizeMiddleware.js +165 -0
  152. package/dist/src/middlewares/ValidationMiddleware.js +2 -2
  153. package/dist/src/mvc/Controller.d.ts +7 -0
  154. package/dist/src/mvc/Controller.d.ts.map +1 -1
  155. package/dist/src/mvc/Controller.js +22 -0
  156. package/dist/src/mvc/Model.d.ts +63 -11
  157. package/dist/src/mvc/Model.d.ts.map +1 -1
  158. package/dist/src/mvc/Model.js +292 -11
  159. package/dist/src/realtime/Decorators.d.ts +33 -0
  160. package/dist/src/realtime/Decorators.d.ts.map +1 -0
  161. package/dist/src/realtime/Decorators.js +48 -0
  162. package/dist/src/realtime/GatewayManager.d.ts +17 -0
  163. package/dist/src/realtime/GatewayManager.d.ts.map +1 -0
  164. package/dist/src/realtime/GatewayManager.js +85 -0
  165. package/dist/src/schema/Schema.d.ts +2 -2
  166. package/dist/src/schema/Schema.d.ts.map +1 -1
  167. package/dist/src/schema/Schema.js +19 -19
  168. package/dist/src/swagger/SwaggerModule.d.ts +288 -0
  169. package/dist/src/swagger/SwaggerModule.d.ts.map +1 -0
  170. package/dist/src/swagger/SwaggerModule.js +340 -0
  171. package/dist/src/swagger/decorators.d.ts +274 -0
  172. package/dist/src/swagger/decorators.d.ts.map +1 -0
  173. package/dist/src/swagger/decorators.js +430 -0
  174. package/dist/src/swagger/index.d.ts +9 -0
  175. package/dist/src/swagger/index.d.ts.map +1 -0
  176. package/dist/src/swagger/index.js +16 -0
  177. package/dist/src/testing/Test.d.ts +27 -0
  178. package/dist/src/testing/Test.d.ts.map +1 -0
  179. package/dist/src/testing/Test.js +75 -0
  180. package/dist/src/testing/TestHelper.d.ts +82 -0
  181. package/dist/src/testing/TestHelper.d.ts.map +1 -0
  182. package/dist/src/testing/TestHelper.js +177 -0
  183. package/dist/src/types/index.d.ts +2 -0
  184. package/dist/src/types/index.d.ts.map +1 -1
  185. package/dist/src/utils/ApiResource.d.ts +130 -0
  186. package/dist/src/utils/ApiResource.d.ts.map +1 -0
  187. package/dist/src/utils/ApiResource.js +236 -0
  188. package/dist/src/utils/ApiVersioning.d.ts +45 -0
  189. package/dist/src/utils/ApiVersioning.d.ts.map +1 -0
  190. package/dist/src/utils/ApiVersioning.js +189 -0
  191. package/dist/src/utils/ErrorHandler.d.ts +21 -16
  192. package/dist/src/utils/ErrorHandler.d.ts.map +1 -1
  193. package/dist/src/utils/ErrorHandler.js +45 -90
  194. package/dist/src/utils/Pipeline.d.ts +64 -0
  195. package/dist/src/utils/Pipeline.d.ts.map +1 -0
  196. package/dist/src/utils/Pipeline.js +131 -0
  197. package/dist/src/utils/QueryParser.d.ts +67 -0
  198. package/dist/src/utils/QueryParser.d.ts.map +1 -0
  199. package/dist/src/utils/QueryParser.js +121 -0
  200. package/package.json +3 -1
  201. package/src/auth/EmailVerification.ts +231 -0
  202. package/src/auth/OAuth.ts +309 -0
  203. package/src/auth/RefreshToken.ts +261 -0
  204. package/src/auth/TwoFactor.ts +251 -0
  205. package/src/cache/TaggedCache.ts +353 -0
  206. package/src/cli/commands/Dashboard.ts +70 -0
  207. package/src/cli/index.ts +2 -0
  208. package/src/config/ConfigManager.ts +233 -0
  209. package/src/container/Container.ts +107 -17
  210. package/src/container/Scope.ts +227 -0
  211. package/src/core/AOP.ts +302 -0
  212. package/src/core/Application.ts +224 -0
  213. package/src/core/Decorators.ts +512 -0
  214. package/src/core/Http2Server.ts +475 -0
  215. package/src/core/Lifecycle.ts +45 -0
  216. package/src/core/Module.ts +612 -0
  217. package/src/core/Router.ts +35 -12
  218. package/src/core/Server.ts +3 -0
  219. package/src/core/ServiceProvider.ts +137 -0
  220. package/src/core/Tracing.ts +69 -0
  221. package/src/core/exceptions/CanxException.ts +7 -0
  222. package/src/core/exceptions/ConflictException.ts +3 -2
  223. package/src/core/exceptions/NotFoundException.ts +3 -1
  224. package/src/core/exceptions/ServiceUnavailableException.ts +3 -3
  225. package/src/core/exceptions/ValidationException.ts +12 -3
  226. package/src/cqrs/CqrsModule.ts +520 -0
  227. package/src/cqrs/EventSourcing.ts +570 -0
  228. package/src/cqrs/index.ts +68 -0
  229. package/src/database/Factory.ts +140 -0
  230. package/src/devtools/DevToolsModule.ts +46 -0
  231. package/src/features/AsyncApi.ts +109 -0
  232. package/src/generator/ClientGenerator.ts +37 -13
  233. package/src/generator/OpenAPIGenerator.ts +432 -0
  234. package/src/graphql/CodeFirst.ts +729 -0
  235. package/src/graphql/Federation.ts +389 -0
  236. package/src/graphql/GraphQLAdapter.ts +266 -0
  237. package/src/graphql/SchemaFirst.ts +312 -0
  238. package/src/graphql/index.ts +110 -0
  239. package/src/graphql/types.d.ts +47 -0
  240. package/src/health/HealthModule.ts +199 -0
  241. package/src/index.ts +624 -14
  242. package/src/microservices/Broker.ts +413 -0
  243. package/src/microservices/Transport.ts +421 -0
  244. package/src/microservices/transports/GrpcTransport.ts +334 -0
  245. package/src/microservices/transports/KafkaTransport.ts +347 -0
  246. package/src/microservices/transports/MqttTransport.ts +324 -0
  247. package/src/microservices/transports/NatsTransport.ts +246 -0
  248. package/src/microservices/transports/RedisTransport.ts +264 -0
  249. package/src/microservices/transports/index.ts +49 -0
  250. package/src/microservices/transports/types.d.ts +57 -0
  251. package/src/middlewares/HelmetMiddleware.ts +246 -0
  252. package/src/middlewares/RateLimiter.ts +285 -0
  253. package/src/middlewares/SanitizeMiddleware.ts +212 -0
  254. package/src/middlewares/ValidationMiddleware.ts +2 -2
  255. package/src/mvc/Controller.ts +27 -0
  256. package/src/mvc/Model.ts +373 -19
  257. package/src/realtime/Decorators.ts +60 -0
  258. package/src/realtime/GatewayManager.ts +97 -0
  259. package/src/schema/Schema.ts +20 -20
  260. package/src/swagger/SwaggerModule.ts +618 -0
  261. package/src/swagger/decorators.ts +665 -0
  262. package/src/swagger/index.ts +96 -0
  263. package/src/testing/Test.ts +103 -0
  264. package/src/testing/TestHelper.ts +223 -0
  265. package/src/types/index.ts +2 -0
  266. package/src/utils/ApiResource.ts +335 -0
  267. package/src/utils/ApiVersioning.ts +243 -0
  268. package/src/utils/ErrorHandler.ts +48 -97
  269. package/src/utils/Pipeline.ts +174 -0
  270. package/src/utils/QueryParser.ts +164 -0
  271. package/src/middlewares/RateLimitMiddleware.ts +0 -62
package/cli/bin.ts CHANGED
@@ -596,6 +596,194 @@ const commands: Record<string, { description: string; handler: (args: string[])
596
596
  },
597
597
  },
598
598
 
599
+ 'version:list': {
600
+ description: 'List available CanxJS versions from NPM',
601
+ handler: async (args) => {
602
+ console.log('\n📦 Fetching available versions from NPM...\n');
603
+ try {
604
+ const res = await fetch('https://registry.npmjs.org/canxjs');
605
+ if (!res.ok) throw new Error('Failed to fetch from NPM registry');
606
+
607
+ const data = await res.json() as { versions: Record<string, any>; 'dist-tags': Record<string, string> };
608
+ const versions = Object.keys(data.versions).reverse();
609
+ const latest = data['dist-tags']?.latest || versions[0];
610
+
611
+ // Get current version
612
+ let currentVersion = 'unknown';
613
+ try {
614
+ const pkg = JSON.parse(await Bun.file('package.json').text());
615
+ currentVersion = pkg.dependencies?.canxjs?.replace(/[\^~]/, '') || 'not installed';
616
+ } catch {}
617
+
618
+ console.log(` Current: ${currentVersion}`);
619
+ console.log(` Latest: ${latest}\n`);
620
+ console.log(' Available versions (newest first):');
621
+
622
+ const limit = args.includes('--all') ? versions.length : 10;
623
+ for (let i = 0; i < Math.min(limit, versions.length); i++) {
624
+ const v = versions[i];
625
+ const marker = v === currentVersion ? ' ← installed' : (v === latest ? ' ★ latest' : '');
626
+ console.log(` ${v}${marker}`);
627
+ }
628
+
629
+ if (versions.length > limit) {
630
+ console.log(`\n ... and ${versions.length - limit} more (use --all to see all)`);
631
+ }
632
+ console.log('');
633
+ } catch (e: any) {
634
+ console.error('❌ Failed to fetch versions:', e.message);
635
+ }
636
+ },
637
+ },
638
+
639
+ upgrade: {
640
+ description: 'Upgrade CanxJS to latest or specified version',
641
+ handler: async (args) => {
642
+ const targetVersion = args[0] || 'latest';
643
+ console.log('\n🚀 CanxJS Upgrade\n');
644
+
645
+ try {
646
+ // Get current version
647
+ let currentVersion = 'unknown';
648
+ try {
649
+ const pkg = JSON.parse(await Bun.file('package.json').text());
650
+ currentVersion = pkg.dependencies?.canxjs?.replace(/[\^~]/, '') || 'not installed';
651
+ } catch {}
652
+
653
+ // Get target version from NPM
654
+ let resolvedVersion = targetVersion;
655
+ if (targetVersion === 'latest') {
656
+ const res = await fetch('https://registry.npmjs.org/canxjs/latest');
657
+ if (!res.ok) throw new Error('Failed to fetch latest version');
658
+ const data = await res.json() as { version: string };
659
+ resolvedVersion = data.version;
660
+ } else {
661
+ // Validate version exists
662
+ const res = await fetch(`https://registry.npmjs.org/canxjs/${targetVersion}`);
663
+ if (!res.ok) throw new Error(`Version ${targetVersion} not found on NPM`);
664
+ const data = await res.json() as { version: string };
665
+ resolvedVersion = data.version;
666
+ }
667
+
668
+ console.log(` Current version: ${currentVersion}`);
669
+ console.log(` Target version: ${resolvedVersion}\n`);
670
+
671
+ if (currentVersion === resolvedVersion) {
672
+ console.log('✅ Already on the target version!\n');
673
+ return;
674
+ }
675
+
676
+ // Check if we're downgrading (only for valid semantic versions)
677
+ // Skip downgrade check for workspace:, unknown, not installed, or non-semver formats
678
+ const isValidSemver = (v: string) => /^\d+\.\d+\.\d+/.test(v);
679
+ const isDowngrade = isValidSemver(currentVersion) &&
680
+ isValidSemver(resolvedVersion) &&
681
+ resolvedVersion.localeCompare(currentVersion, undefined, { numeric: true }) < 0;
682
+
683
+ if (isDowngrade && !args.includes('--force')) {
684
+ console.log('⚠️ This would downgrade your version. Use --force to confirm.\n');
685
+ console.log(' Or use: canx downgrade ' + resolvedVersion + '\n');
686
+ return;
687
+ }
688
+
689
+ // Perform upgrade
690
+ console.log('📥 Installing canxjs@' + resolvedVersion + '...\n');
691
+ const result = spawnSync('bun', ['add', `canxjs@${resolvedVersion}`], {
692
+ stdio: 'inherit',
693
+ cwd: process.cwd()
694
+ });
695
+
696
+ if (result.status === 0) {
697
+ console.log('\n✅ Successfully upgraded to canxjs@' + resolvedVersion + '!\n');
698
+ console.log('📝 Post-upgrade recommendations:');
699
+ console.log(' 1. Clear any caches: rm -rf node_modules/.cache');
700
+ console.log(' 2. Review CHANGELOG for breaking changes');
701
+ console.log(' 3. Run your test suite to verify compatibility\n');
702
+ } else {
703
+ console.error('\n❌ Upgrade failed. Please check the error above.\n');
704
+ }
705
+ } catch (e: any) {
706
+ console.error('❌ Upgrade failed:', e.message);
707
+ }
708
+ },
709
+ },
710
+
711
+ downgrade: {
712
+ description: 'Downgrade CanxJS to a specific version',
713
+ handler: async (args) => {
714
+ const targetVersion = args[0];
715
+ console.log('\n⬇️ CanxJS Downgrade\n');
716
+
717
+ if (!targetVersion) {
718
+ console.error('Usage: canx downgrade <version>');
719
+ console.log('\nExample: canx downgrade 1.0.0');
720
+ console.log('\nUse "canx version:list" to see available versions.\n');
721
+ process.exit(1);
722
+ }
723
+
724
+ try {
725
+ // Get current version
726
+ let currentVersion = 'unknown';
727
+ try {
728
+ const pkg = JSON.parse(await Bun.file('package.json').text());
729
+ currentVersion = pkg.dependencies?.canxjs?.replace(/[\^~]/, '') || 'not installed';
730
+ } catch {}
731
+
732
+ // Validate version exists on NPM
733
+ const res = await fetch(`https://registry.npmjs.org/canxjs/${targetVersion}`);
734
+ if (!res.ok) {
735
+ console.error(`❌ Version ${targetVersion} not found on NPM.`);
736
+ console.log('\nUse "canx version:list" to see available versions.\n');
737
+ process.exit(1);
738
+ }
739
+
740
+ console.log(` Current version: ${currentVersion}`);
741
+ console.log(` Target version: ${targetVersion}\n`);
742
+
743
+ if (currentVersion === targetVersion) {
744
+ console.log('✅ Already on the target version!\n');
745
+ return;
746
+ }
747
+
748
+ // Warning for downgrade
749
+ console.log('⚠️ WARNING: Downgrading may cause issues if your code uses');
750
+ console.log(' features that were added in newer versions.\n');
751
+
752
+ if (!args.includes('--force')) {
753
+ console.log(' Add --force to proceed with the downgrade.\n');
754
+ return;
755
+ }
756
+
757
+ // Perform downgrade
758
+ console.log('📥 Installing canxjs@' + targetVersion + '...\n');
759
+ const result = spawnSync('bun', ['add', `canxjs@${targetVersion}`], {
760
+ stdio: 'inherit',
761
+ cwd: process.cwd()
762
+ });
763
+
764
+ if (result.status === 0) {
765
+ console.log('\n✅ Successfully downgraded to canxjs@' + targetVersion + '!\n');
766
+ console.log('📝 Post-downgrade recommendations:');
767
+ console.log(' 1. Review your code for any incompatible features');
768
+ console.log(' 2. Run your test suite to verify compatibility');
769
+ console.log(' 3. Check the CHANGELOG for breaking changes\n');
770
+ } else {
771
+ console.error('\n❌ Downgrade failed. Please check the error above.\n');
772
+ }
773
+ } catch (e: any) {
774
+ console.error('❌ Downgrade failed:', e.message);
775
+ }
776
+ },
777
+ },
778
+
779
+ 'self-update': {
780
+ description: 'Update CanxJS CLI to the latest version (alias for upgrade)',
781
+ handler: async (args) => {
782
+ // Delegate to upgrade command
783
+ await commands.upgrade.handler(['latest', ...args]);
784
+ },
785
+ },
786
+
599
787
  help: {
600
788
  description: 'Show help',
601
789
  handler: () => showHelp(),
@@ -623,6 +811,7 @@ Commands:`);
623
811
  'Development': ['serve', 'build', 'routes', 'generate:client'],
624
812
  'Generators': ['make:controller', 'make:model', 'make:middleware', 'make:migration', 'make:seeder', 'make:service', 'make:notification'],
625
813
  'Database': ['db:migrate', 'db:rollback', 'db:seed', 'db:fresh'],
814
+ 'Version Management': ['upgrade', 'downgrade', 'version:list', 'self-update'],
626
815
  'Other': ['version', 'help'],
627
816
  };
628
817
 
@@ -641,6 +830,10 @@ Examples:
641
830
  canx make:controller Post # Generate PostController
642
831
  canx db:migrate # Run pending migrations
643
832
  canx db:seed # Run all seeders
833
+ canx upgrade # Upgrade to latest version
834
+ canx upgrade 2.0.0 # Upgrade to specific version
835
+ canx downgrade 1.5.0 --force # Downgrade to specific version
836
+ canx version:list # List available versions
644
837
  `);
645
838
  }
646
839
 
@@ -0,0 +1,75 @@
1
+ /**
2
+ * CanxJS Email Verification
3
+ * Signed URL generation and verification for email confirmation
4
+ */
5
+ import type { CanxRequest, CanxResponse, MiddlewareHandler } from '../types';
6
+ export interface EmailVerificationConfig {
7
+ secret: string;
8
+ expiresIn?: number;
9
+ baseUrl: string;
10
+ verifyPath?: string;
11
+ }
12
+ export interface VerificationPayload {
13
+ id: string | number;
14
+ email: string;
15
+ expires: number;
16
+ signature: string;
17
+ }
18
+ export declare class EmailVerification {
19
+ private config;
20
+ constructor(config: EmailVerificationConfig);
21
+ /**
22
+ * Generate HMAC signature
23
+ */
24
+ private sign;
25
+ /**
26
+ * Generate verification URL
27
+ */
28
+ generateUrl(userId: string | number, email: string): Promise<string>;
29
+ /**
30
+ * Verify signed URL parameters
31
+ */
32
+ verify(params: {
33
+ id: string;
34
+ email: string;
35
+ expires: string;
36
+ signature: string;
37
+ }): Promise<{
38
+ valid: boolean;
39
+ userId?: string | number;
40
+ email?: string;
41
+ error?: string;
42
+ }>;
43
+ /**
44
+ * Middleware to handle verification endpoint
45
+ */
46
+ verifyMiddleware(onSuccess: (userId: string | number, email: string, req: CanxRequest, res: CanxResponse) => void | Promise<void>, onError?: (error: string, req: CanxRequest, res: CanxResponse) => void | Promise<void>): MiddlewareHandler;
47
+ }
48
+ export declare class PasswordReset {
49
+ private config;
50
+ constructor(config: EmailVerificationConfig);
51
+ private sign;
52
+ /**
53
+ * Generate password reset URL
54
+ */
55
+ generateUrl(userId: string | number, email: string): Promise<string>;
56
+ private generateToken;
57
+ /**
58
+ * Verify reset token
59
+ */
60
+ verify(params: {
61
+ id: string;
62
+ email: string;
63
+ token: string;
64
+ expires: string;
65
+ signature: string;
66
+ }): Promise<{
67
+ valid: boolean;
68
+ userId?: string | number;
69
+ email?: string;
70
+ error?: string;
71
+ }>;
72
+ }
73
+ export declare function createEmailVerification(config: EmailVerificationConfig): EmailVerification;
74
+ export declare function createPasswordReset(config: EmailVerificationConfig): PasswordReset;
75
+ //# sourceMappingURL=EmailVerification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmailVerification.d.ts","sourceRoot":"","sources":["../../../src/auth/EmailVerification.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAM7E,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAoC;gBAEtC,MAAM,EAAE,uBAAuB;IAQ3C;;OAEG;YACW,IAAI;IAiBlB;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAe1E;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE;QACnB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAoBzF;;OAEG;IACH,gBAAgB,CACd,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAChH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACrF,iBAAiB;CAuBrB;AAMD,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAoC;gBAEtC,MAAM,EAAE,uBAAuB;YAQ7B,IAAI;IAiBlB;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAiB5D,aAAa;IAM3B;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE;QACnB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAiB1F;AAGD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,uBAAuB,GAAG,iBAAiB,CAE1F;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,uBAAuB,GAAG,aAAa,CAElF"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * CanxJS Email Verification
3
+ * Signed URL generation and verification for email confirmation
4
+ */
5
+ // ============================================
6
+ // Signed URL Generator
7
+ // ============================================
8
+ export class EmailVerification {
9
+ config;
10
+ constructor(config) {
11
+ this.config = {
12
+ expiresIn: config.expiresIn || 86400, // 24 hours
13
+ verifyPath: config.verifyPath || '/auth/verify-email',
14
+ ...config,
15
+ };
16
+ }
17
+ /**
18
+ * Generate HMAC signature
19
+ */
20
+ async sign(data) {
21
+ const encoder = new TextEncoder();
22
+ const key = await crypto.subtle.importKey('raw', encoder.encode(this.config.secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
23
+ const signature = await crypto.subtle.sign('HMAC', key, encoder.encode(data));
24
+ return btoa(String.fromCharCode(...new Uint8Array(signature)))
25
+ .replace(/\+/g, '-')
26
+ .replace(/\//g, '_')
27
+ .replace(/=+$/, '');
28
+ }
29
+ /**
30
+ * Generate verification URL
31
+ */
32
+ async generateUrl(userId, email) {
33
+ const expires = Math.floor(Date.now() / 1000) + this.config.expiresIn;
34
+ const dataToSign = `${userId}|${email}|${expires}`;
35
+ const signature = await this.sign(dataToSign);
36
+ const params = new URLSearchParams({
37
+ id: String(userId),
38
+ email,
39
+ expires: String(expires),
40
+ signature,
41
+ });
42
+ return `${this.config.baseUrl}${this.config.verifyPath}?${params.toString()}`;
43
+ }
44
+ /**
45
+ * Verify signed URL parameters
46
+ */
47
+ async verify(params) {
48
+ const { id, email, expires, signature } = params;
49
+ // Check expiration
50
+ const expiresNum = parseInt(expires, 10);
51
+ if (isNaN(expiresNum) || expiresNum < Math.floor(Date.now() / 1000)) {
52
+ return { valid: false, error: 'Verification link has expired' };
53
+ }
54
+ // Verify signature
55
+ const dataToSign = `${id}|${email}|${expires}`;
56
+ const expectedSignature = await this.sign(dataToSign);
57
+ if (signature !== expectedSignature) {
58
+ return { valid: false, error: 'Invalid signature' };
59
+ }
60
+ return { valid: true, userId: id, email };
61
+ }
62
+ /**
63
+ * Middleware to handle verification endpoint
64
+ */
65
+ verifyMiddleware(onSuccess, onError) {
66
+ return async (req, res) => {
67
+ const { id, email, expires, signature } = req.query;
68
+ if (!id || !email || !expires || !signature) {
69
+ if (onError) {
70
+ return onError('Missing required parameters', req, res);
71
+ }
72
+ return res.status(400).json({ error: 'Missing required parameters' });
73
+ }
74
+ const result = await this.verify({ id, email, expires, signature });
75
+ if (!result.valid) {
76
+ if (onError) {
77
+ return onError(result.error, req, res);
78
+ }
79
+ return res.status(400).json({ error: result.error });
80
+ }
81
+ return onSuccess(result.userId, result.email, req, res);
82
+ };
83
+ }
84
+ }
85
+ // ============================================
86
+ // Password Reset (Similar pattern)
87
+ // ============================================
88
+ export class PasswordReset {
89
+ config;
90
+ constructor(config) {
91
+ this.config = {
92
+ expiresIn: config.expiresIn || 3600, // 1 hour
93
+ verifyPath: config.verifyPath || '/auth/reset-password',
94
+ ...config,
95
+ };
96
+ }
97
+ async sign(data) {
98
+ const encoder = new TextEncoder();
99
+ const key = await crypto.subtle.importKey('raw', encoder.encode(this.config.secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
100
+ const signature = await crypto.subtle.sign('HMAC', key, encoder.encode(data));
101
+ return btoa(String.fromCharCode(...new Uint8Array(signature)))
102
+ .replace(/\+/g, '-')
103
+ .replace(/\//g, '_')
104
+ .replace(/=+$/, '');
105
+ }
106
+ /**
107
+ * Generate password reset URL
108
+ */
109
+ async generateUrl(userId, email) {
110
+ const expires = Math.floor(Date.now() / 1000) + this.config.expiresIn;
111
+ const token = await this.generateToken();
112
+ const dataToSign = `${userId}|${email}|${token}|${expires}`;
113
+ const signature = await this.sign(dataToSign);
114
+ const params = new URLSearchParams({
115
+ id: String(userId),
116
+ email,
117
+ token,
118
+ expires: String(expires),
119
+ signature,
120
+ });
121
+ return `${this.config.baseUrl}${this.config.verifyPath}?${params.toString()}`;
122
+ }
123
+ async generateToken() {
124
+ const array = new Uint8Array(32);
125
+ crypto.getRandomValues(array);
126
+ return Array.from(array, b => b.toString(16).padStart(2, '0')).join('');
127
+ }
128
+ /**
129
+ * Verify reset token
130
+ */
131
+ async verify(params) {
132
+ const { id, email, token, expires, signature } = params;
133
+ const expiresNum = parseInt(expires, 10);
134
+ if (isNaN(expiresNum) || expiresNum < Math.floor(Date.now() / 1000)) {
135
+ return { valid: false, error: 'Reset link has expired' };
136
+ }
137
+ const dataToSign = `${id}|${email}|${token}|${expires}`;
138
+ const expectedSignature = await this.sign(dataToSign);
139
+ if (signature !== expectedSignature) {
140
+ return { valid: false, error: 'Invalid signature' };
141
+ }
142
+ return { valid: true, userId: id, email };
143
+ }
144
+ }
145
+ // Factory functions
146
+ export function createEmailVerification(config) {
147
+ return new EmailVerification(config);
148
+ }
149
+ export function createPasswordReset(config) {
150
+ return new PasswordReset(config);
151
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * CanxJS OAuth2 Provider
3
+ * Social login integration for Google, GitHub, Facebook, Discord
4
+ */
5
+ import type { CanxRequest, CanxResponse, MiddlewareHandler } from '../types';
6
+ export interface OAuthProvider {
7
+ name: string;
8
+ clientId: string;
9
+ clientSecret: string;
10
+ redirectUri: string;
11
+ scopes: string[];
12
+ authUrl: string;
13
+ tokenUrl: string;
14
+ userInfoUrl: string;
15
+ }
16
+ export interface OAuthUser {
17
+ id: string;
18
+ email: string;
19
+ name: string;
20
+ avatar?: string;
21
+ provider: string;
22
+ accessToken: string;
23
+ refreshToken?: string;
24
+ raw: Record<string, unknown>;
25
+ }
26
+ export interface OAuthConfig {
27
+ providers: Record<string, Partial<OAuthProvider>>;
28
+ defaultScopes?: Record<string, string[]>;
29
+ }
30
+ export declare class OAuth {
31
+ private providers;
32
+ private stateStore;
33
+ /**
34
+ * Configure OAuth providers
35
+ */
36
+ configure(config: OAuthConfig): void;
37
+ /**
38
+ * Generate a secure state token
39
+ */
40
+ private generateState;
41
+ /**
42
+ * Get authorization URL for a provider
43
+ */
44
+ getAuthUrl(providerName: string, additionalParams?: Record<string, string>): string;
45
+ /**
46
+ * Handle OAuth callback and exchange code for tokens
47
+ */
48
+ handleCallback(providerName: string, code: string, state: string): Promise<OAuthUser>;
49
+ /**
50
+ * Normalize user data from different providers
51
+ */
52
+ private normalizeUser;
53
+ /**
54
+ * Redirect middleware for OAuth flow
55
+ */
56
+ redirect(providerName: string): MiddlewareHandler;
57
+ /**
58
+ * Callback middleware for OAuth flow
59
+ */
60
+ callback(providerName: string, onSuccess: (user: OAuthUser, req: CanxRequest, res: CanxResponse) => void | Promise<void>): MiddlewareHandler;
61
+ }
62
+ export declare const oauth: OAuth;
63
+ export declare function initOAuth(config: OAuthConfig): void;
64
+ //# sourceMappingURL=OAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuth.d.ts","sourceRoot":"","sources":["../../../src/auth/OAuth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAM7E,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC1C;AA4CD,qBAAa,KAAK;IAChB,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,UAAU,CAAmE;IAErF;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,WAAW;IAsB7B;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM;IAyBnF;;OAEG;IACG,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAoD3F;;OAEG;IACH,OAAO,CAAC,aAAa;IAkErB;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,iBAAiB;IAOjD;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,iBAAiB;CAiB7I;AAGD,eAAO,MAAM,KAAK,OAAc,CAAC;AAGjC,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,QAE5C"}