sqlew 3.8.1 → 3.9.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 (881) hide show
  1. package/CHANGELOG.md +155 -285
  2. package/README.md +150 -32
  3. package/assets/sample-agents/sqlew-architect.md +72 -17
  4. package/assets/sample-agents/sqlew-researcher.md +62 -1
  5. package/assets/sample-agents/sqlew-scrum-master.md +5 -1
  6. package/assets/sample-commands/README.md +57 -0
  7. package/assets/sample-commands/sqw-documentor.md +158 -0
  8. package/assets/sample-commands/sqw-plan.md +301 -0
  9. package/assets/sample-commands/sqw-research.md +298 -0
  10. package/assets/sample-commands/sqw-review.md +340 -0
  11. package/assets/sample-commands/sqw-scrum.md +423 -0
  12. package/assets/sample-commands/sqw-secretary.md +187 -0
  13. package/dist/adapters/sqlite-adapter.d.ts +0 -6
  14. package/dist/adapters/sqlite-adapter.d.ts.map +1 -1
  15. package/dist/adapters/sqlite-adapter.js +10 -14
  16. package/dist/adapters/sqlite-adapter.js.map +1 -1
  17. package/dist/cli/db-dump.d.ts +1 -1
  18. package/dist/cli/db-dump.d.ts.map +1 -1
  19. package/dist/cli/db-dump.js +1 -1
  20. package/dist/cli/db-dump.js.map +1 -1
  21. package/dist/config/knex/bootstrap/20251025021352_fix_mysql_index_syntax.d.ts +4 -0
  22. package/dist/config/knex/bootstrap/20251025021352_fix_mysql_index_syntax.d.ts.map +1 -0
  23. package/dist/config/knex/bootstrap/20251025021352_fix_mysql_index_syntax.js +146 -0
  24. package/dist/config/knex/bootstrap/20251025021352_fix_mysql_index_syntax.js.map +1 -0
  25. package/dist/config/knex/enhancements/20251112000001_fix_task_file_links_schema_v3_9_0.d.ts +22 -0
  26. package/dist/config/knex/enhancements/20251112000001_fix_task_file_links_schema_v3_9_0.d.ts.map +1 -0
  27. package/dist/config/knex/enhancements/20251112000001_fix_task_file_links_schema_v3_9_0.js +106 -0
  28. package/dist/config/knex/enhancements/20251112000001_fix_task_file_links_schema_v3_9_0.js.map +1 -0
  29. package/dist/config/knex/enhancements/20251112000002_fix_task_pruned_files_schema_v3_9_0.d.ts +21 -0
  30. package/dist/config/knex/enhancements/20251112000002_fix_task_pruned_files_schema_v3_9_0.d.ts.map +1 -0
  31. package/dist/config/knex/enhancements/20251112000002_fix_task_pruned_files_schema_v3_9_0.js +106 -0
  32. package/dist/config/knex/enhancements/20251112000002_fix_task_pruned_files_schema_v3_9_0.js.map +1 -0
  33. package/dist/config/knex/enhancements/20251114000000_fix_v_tagged_decisions_numeric_support.d.ts +21 -0
  34. package/dist/config/knex/enhancements/20251114000000_fix_v_tagged_decisions_numeric_support.d.ts.map +1 -0
  35. package/dist/config/knex/enhancements/20251114000000_fix_v_tagged_decisions_numeric_support.js +91 -0
  36. package/dist/config/knex/enhancements/20251114000000_fix_v_tagged_decisions_numeric_support.js.map +1 -0
  37. package/dist/config/knex/enhancements/20251114120000_add_suggest_tool_to_help_system_v3_9_0.d.ts +15 -0
  38. package/dist/config/knex/enhancements/20251114120000_add_suggest_tool_to_help_system_v3_9_0.d.ts.map +1 -0
  39. package/dist/config/knex/enhancements/20251114120000_add_suggest_tool_to_help_system_v3_9_0.js +270 -0
  40. package/dist/config/knex/enhancements/20251114120000_add_suggest_tool_to_help_system_v3_9_0.js.map +1 -0
  41. package/dist/config/knex/enhancements/20251114121000_add_suggest_tool_use_cases_v3_9_0.d.ts +15 -0
  42. package/dist/config/knex/enhancements/20251114121000_add_suggest_tool_use_cases_v3_9_0.d.ts.map +1 -0
  43. package/dist/config/knex/enhancements/20251114121000_add_suggest_tool_use_cases_v3_9_0.js +241 -0
  44. package/dist/config/knex/enhancements/20251114121000_add_suggest_tool_use_cases_v3_9_0.js.map +1 -0
  45. package/dist/config/knex/enhancements/20251114130000_seed_builtin_policies_v3_9_0.d.ts +16 -0
  46. package/dist/config/knex/enhancements/20251114130000_seed_builtin_policies_v3_9_0.d.ts.map +1 -0
  47. package/dist/config/knex/enhancements/20251114130000_seed_builtin_policies_v3_9_0.js +168 -0
  48. package/dist/config/knex/enhancements/20251114130000_seed_builtin_policies_v3_9_0.js.map +1 -0
  49. package/dist/config/knex/enhancements/20251114140000_add_policy_help_v3_9_0.d.ts +14 -0
  50. package/dist/config/knex/enhancements/20251114140000_add_policy_help_v3_9_0.d.ts.map +1 -0
  51. package/dist/config/knex/enhancements/20251114140000_add_policy_help_v3_9_0.js +228 -0
  52. package/dist/config/knex/enhancements/20251114140000_add_policy_help_v3_9_0.js.map +1 -0
  53. package/dist/config/knex/enhancements/20251114141000_add_policy_use_cases_v3_9_0.d.ts +14 -0
  54. package/dist/config/knex/enhancements/20251114141000_add_policy_use_cases_v3_9_0.d.ts.map +1 -0
  55. package/dist/config/knex/enhancements/20251114141000_add_policy_use_cases_v3_9_0.js +237 -0
  56. package/dist/config/knex/enhancements/20251114141000_add_policy_use_cases_v3_9_0.js.map +1 -0
  57. package/dist/config/knex/enhancements/20251114150000_fix_policy_unique_constraint_v3_9_0.d.ts +14 -0
  58. package/dist/config/knex/enhancements/20251114150000_fix_policy_unique_constraint_v3_9_0.d.ts.map +1 -0
  59. package/dist/config/knex/enhancements/20251114150000_fix_policy_unique_constraint_v3_9_0.js +61 -0
  60. package/dist/config/knex/enhancements/20251114150000_fix_policy_unique_constraint_v3_9_0.js.map +1 -0
  61. package/dist/config/knex/enhancements/20251115000000_fix_task_decision_links_unique_constraint.d.ts +21 -0
  62. package/dist/config/knex/enhancements/20251115000000_fix_task_decision_links_unique_constraint.d.ts.map +1 -0
  63. package/dist/config/knex/enhancements/20251115000000_fix_task_decision_links_unique_constraint.js +127 -0
  64. package/dist/config/knex/enhancements/20251115000000_fix_task_decision_links_unique_constraint.js.map +1 -0
  65. package/dist/config/knex/enhancements/20251115100000_fix_read_keyword_index_v3_9_0.d.ts +15 -0
  66. package/dist/config/knex/enhancements/20251115100000_fix_read_keyword_index_v3_9_0.d.ts.map +1 -0
  67. package/dist/config/knex/enhancements/20251115100000_fix_read_keyword_index_v3_9_0.js +69 -0
  68. package/dist/config/knex/enhancements/20251115100000_fix_read_keyword_index_v3_9_0.js.map +1 -0
  69. package/dist/config/knex/enhancements/20251115110000_fix_cross_database_timestamps_v3_9_0.d.ts +15 -0
  70. package/dist/config/knex/enhancements/20251115110000_fix_cross_database_timestamps_v3_9_0.d.ts.map +1 -0
  71. package/dist/config/knex/enhancements/20251115110000_fix_cross_database_timestamps_v3_9_0.js +132 -0
  72. package/dist/config/knex/enhancements/20251115110000_fix_cross_database_timestamps_v3_9_0.js.map +1 -0
  73. package/dist/config/knex/enhancements/20251115120000_fix_all_cross_db_issues_v3_9_0.d.ts +18 -0
  74. package/dist/config/knex/enhancements/20251115120000_fix_all_cross_db_issues_v3_9_0.d.ts.map +1 -0
  75. package/dist/config/knex/enhancements/20251115120000_fix_all_cross_db_issues_v3_9_0.js +47 -0
  76. package/dist/config/knex/enhancements/20251115120000_fix_all_cross_db_issues_v3_9_0.js.map +1 -0
  77. package/dist/config/knex/enhancements/20251118000000_fix_native_db_test_issues_v3_9_1.d.ts +20 -0
  78. package/dist/config/knex/enhancements/20251118000000_fix_native_db_test_issues_v3_9_1.d.ts.map +1 -0
  79. package/dist/config/knex/enhancements/20251118000000_fix_native_db_test_issues_v3_9_1.js +119 -0
  80. package/dist/config/knex/enhancements/20251118000000_fix_native_db_test_issues_v3_9_1.js.map +1 -0
  81. package/dist/config/knex/upgrades/20251111235959_preemptive_fix_cross_database_v3_9_0.d.ts +19 -0
  82. package/dist/config/knex/upgrades/20251111235959_preemptive_fix_cross_database_v3_9_0.d.ts.map +1 -0
  83. package/dist/config/knex/upgrades/20251111235959_preemptive_fix_cross_database_v3_9_0.js +196 -0
  84. package/dist/config/knex/upgrades/20251111235959_preemptive_fix_cross_database_v3_9_0.js.map +1 -0
  85. package/dist/config/knex/upgrades/20251112000000_decision_intelligence_v3_9_0.d.ts +22 -0
  86. package/dist/config/knex/upgrades/20251112000000_decision_intelligence_v3_9_0.d.ts.map +1 -0
  87. package/dist/config/knex/upgrades/20251112000000_decision_intelligence_v3_9_0.js +375 -0
  88. package/dist/config/knex/upgrades/20251112000000_decision_intelligence_v3_9_0.js.map +1 -0
  89. package/dist/config/loader.d.ts.map +1 -1
  90. package/dist/config/loader.js +4 -0
  91. package/dist/config/loader.js.map +1 -1
  92. package/dist/config/minimal-generator.d.ts.map +1 -1
  93. package/dist/config/minimal-generator.js +34 -0
  94. package/dist/config/minimal-generator.js.map +1 -1
  95. package/dist/config/types.d.ts +19 -0
  96. package/dist/config/types.d.ts.map +1 -1
  97. package/dist/config/types.js +8 -0
  98. package/dist/config/types.js.map +1 -1
  99. package/dist/constants.d.ts +30 -0
  100. package/dist/constants.d.ts.map +1 -1
  101. package/dist/constants.js +33 -0
  102. package/dist/constants.js.map +1 -1
  103. package/dist/database/initialization/cleanup.d.ts +1 -1
  104. package/dist/database/initialization/cleanup.d.ts.map +1 -1
  105. package/dist/database/initialization/cleanup.js +15 -1
  106. package/dist/database/initialization/cleanup.js.map +1 -1
  107. package/dist/database/initialization/init.d.ts.map +1 -1
  108. package/dist/database/initialization/init.js +3 -0
  109. package/dist/database/initialization/init.js.map +1 -1
  110. package/dist/database/migrations/20251024010000_upgrade_v1_0_to_v1_1.d.ts +16 -0
  111. package/dist/database/migrations/20251024010000_upgrade_v1_0_to_v1_1.d.ts.map +1 -0
  112. package/dist/database/migrations/20251024010000_upgrade_v1_0_to_v1_1.js +84 -0
  113. package/dist/database/migrations/20251024010000_upgrade_v1_0_to_v1_1.js.map +1 -0
  114. package/dist/database/migrations/20251024020000_upgrade_v2_0_to_v2_1.d.ts +14 -0
  115. package/dist/database/migrations/20251024020000_upgrade_v2_0_to_v2_1.d.ts.map +1 -0
  116. package/dist/database/migrations/20251024020000_upgrade_v2_0_to_v2_1.js +42 -0
  117. package/dist/database/migrations/20251024020000_upgrade_v2_0_to_v2_1.js.map +1 -0
  118. package/dist/database/migrations/20251024030000_upgrade_v2_1_to_v3_0.d.ts +17 -0
  119. package/dist/database/migrations/20251024030000_upgrade_v2_1_to_v3_0.d.ts.map +1 -0
  120. package/dist/database/migrations/20251024030000_upgrade_v2_1_to_v3_0.js +122 -0
  121. package/dist/database/migrations/20251024030000_upgrade_v2_1_to_v3_0.js.map +1 -0
  122. package/dist/database/migrations/20251024040000_upgrade_v3_0_to_v3_2.d.ts +12 -0
  123. package/dist/database/migrations/20251024040000_upgrade_v3_0_to_v3_2.d.ts.map +1 -0
  124. package/dist/database/migrations/20251024040000_upgrade_v3_0_to_v3_2.js +49 -0
  125. package/dist/database/migrations/20251024040000_upgrade_v3_0_to_v3_2.js.map +1 -0
  126. package/dist/database/migrations/20251024050000_upgrade_v3_2_0_to_v3_2_2.d.ts +12 -0
  127. package/dist/database/migrations/20251024050000_upgrade_v3_2_0_to_v3_2_2.d.ts.map +1 -0
  128. package/dist/database/migrations/20251024050000_upgrade_v3_2_0_to_v3_2_2.js +53 -0
  129. package/dist/database/migrations/20251024050000_upgrade_v3_2_0_to_v3_2_2.js.map +1 -0
  130. package/dist/database/migrations/20251024060000_upgrade_v3_4_to_v3_5.d.ts +12 -0
  131. package/dist/database/migrations/20251024060000_upgrade_v3_4_to_v3_5.d.ts.map +1 -0
  132. package/dist/database/migrations/20251024060000_upgrade_v3_4_to_v3_5.js +44 -0
  133. package/dist/database/migrations/20251024060000_upgrade_v3_4_to_v3_5.js.map +1 -0
  134. package/dist/database/migrations/20251024070000_upgrade_v3_5_to_v3_6.d.ts +13 -0
  135. package/dist/database/migrations/20251024070000_upgrade_v3_5_to_v3_6.d.ts.map +1 -0
  136. package/dist/database/migrations/20251024070000_upgrade_v3_5_to_v3_6.js +33 -0
  137. package/dist/database/migrations/20251024070000_upgrade_v3_5_to_v3_6.js.map +1 -0
  138. package/dist/database/migrations/20251025020452_create_master_tables_wrapper.d.ts +17 -0
  139. package/dist/database/migrations/20251025020452_create_master_tables_wrapper.d.ts.map +1 -0
  140. package/dist/database/migrations/20251025020452_create_master_tables_wrapper.js +119 -0
  141. package/dist/database/migrations/20251025020452_create_master_tables_wrapper.js.map +1 -0
  142. package/dist/database/migrations/20251025021152_create_transaction_tables_wrapper.d.ts +15 -0
  143. package/dist/database/migrations/20251025021152_create_transaction_tables_wrapper.d.ts.map +1 -0
  144. package/dist/database/migrations/20251025021152_create_transaction_tables_wrapper.js +282 -0
  145. package/dist/database/migrations/20251025021152_create_transaction_tables_wrapper.js.map +1 -0
  146. package/dist/database/migrations/20251025021351_create_indexes_wrapper.d.ts +21 -0
  147. package/dist/database/migrations/20251025021351_create_indexes_wrapper.d.ts.map +1 -0
  148. package/dist/database/migrations/20251025021351_create_indexes_wrapper.js +83 -0
  149. package/dist/database/migrations/20251025021351_create_indexes_wrapper.js.map +1 -0
  150. package/dist/database/migrations/20251025021352_fix_mysql_index_syntax_wrapper.d.ts +22 -0
  151. package/dist/database/migrations/20251025021352_fix_mysql_index_syntax_wrapper.d.ts.map +1 -0
  152. package/dist/database/migrations/20251025021352_fix_mysql_index_syntax_wrapper.js +94 -0
  153. package/dist/database/migrations/20251025021352_fix_mysql_index_syntax_wrapper.js.map +1 -0
  154. package/dist/database/migrations/20251025021416_seed_master_data_wrapper.d.ts +19 -0
  155. package/dist/database/migrations/20251025021416_seed_master_data_wrapper.d.ts.map +1 -0
  156. package/dist/database/migrations/20251025021416_seed_master_data_wrapper.js +120 -0
  157. package/dist/database/migrations/20251025021416_seed_master_data_wrapper.js.map +1 -0
  158. package/dist/database/migrations/20251025070349_create_views_wrapper.d.ts +14 -0
  159. package/dist/database/migrations/20251025070349_create_views_wrapper.d.ts.map +1 -0
  160. package/dist/database/migrations/20251025070349_create_views_wrapper.js +160 -0
  161. package/dist/database/migrations/20251025070349_create_views_wrapper.js.map +1 -0
  162. package/dist/database/migrations/20251025081221_add_link_type_to_task_decision_links.d.ts +9 -0
  163. package/dist/database/migrations/20251025081221_add_link_type_to_task_decision_links.d.ts.map +1 -0
  164. package/dist/database/migrations/20251025081221_add_link_type_to_task_decision_links.js +21 -0
  165. package/dist/database/migrations/20251025081221_add_link_type_to_task_decision_links.js.map +1 -0
  166. package/dist/database/migrations/20251025082220_fix_task_dependencies_columns.d.ts +13 -0
  167. package/dist/database/migrations/20251025082220_fix_task_dependencies_columns.d.ts.map +1 -0
  168. package/dist/database/migrations/20251025082220_fix_task_dependencies_columns.js +17 -0
  169. package/dist/database/migrations/20251025082220_fix_task_dependencies_columns.js.map +1 -0
  170. package/dist/database/migrations/20251025090000_create_help_system_tables.d.ts +27 -0
  171. package/dist/database/migrations/20251025090000_create_help_system_tables.d.ts.map +1 -0
  172. package/dist/database/migrations/20251025090000_create_help_system_tables.js +120 -0
  173. package/dist/database/migrations/20251025090000_create_help_system_tables.js.map +1 -0
  174. package/dist/database/migrations/20251025090100_seed_help_categories_and_use_cases.d.ts +18 -0
  175. package/dist/database/migrations/20251025090100_seed_help_categories_and_use_cases.d.ts.map +1 -0
  176. package/dist/database/migrations/20251025090100_seed_help_categories_and_use_cases.js +388 -0
  177. package/dist/database/migrations/20251025090100_seed_help_categories_and_use_cases.js.map +1 -0
  178. package/dist/database/migrations/20251025100000_seed_help_metadata.d.ts +20 -0
  179. package/dist/database/migrations/20251025100000_seed_help_metadata.d.ts.map +1 -0
  180. package/dist/database/migrations/20251025100000_seed_help_metadata.js +264 -0
  181. package/dist/database/migrations/20251025100000_seed_help_metadata.js.map +1 -0
  182. package/dist/database/migrations/20251025100100_seed_remaining_use_cases.d.ts +21 -0
  183. package/dist/database/migrations/20251025100100_seed_remaining_use_cases.d.ts.map +1 -0
  184. package/dist/database/migrations/20251025100100_seed_remaining_use_cases.js +281 -0
  185. package/dist/database/migrations/20251025100100_seed_remaining_use_cases.js.map +1 -0
  186. package/dist/database/migrations/20251025120000_add_cascade_to_task_dependencies.d.ts +13 -0
  187. package/dist/database/migrations/20251025120000_add_cascade_to_task_dependencies.d.ts.map +1 -0
  188. package/dist/database/migrations/20251025120000_add_cascade_to_task_dependencies.js +76 -0
  189. package/dist/database/migrations/20251025120000_add_cascade_to_task_dependencies.js.map +1 -0
  190. package/dist/database/migrations/20251027000000_add_agent_reuse_system.d.ts +17 -0
  191. package/dist/database/migrations/20251027000000_add_agent_reuse_system.d.ts.map +1 -0
  192. package/dist/database/migrations/20251027000000_add_agent_reuse_system.js +42 -0
  193. package/dist/database/migrations/20251027000000_add_agent_reuse_system.js.map +1 -0
  194. package/dist/database/migrations/20251027010000_add_task_constraint_to_decision_context.d.ts +10 -0
  195. package/dist/database/migrations/20251027010000_add_task_constraint_to_decision_context.d.ts.map +1 -0
  196. package/dist/database/migrations/20251027010000_add_task_constraint_to_decision_context.js +28 -0
  197. package/dist/database/migrations/20251027010000_add_task_constraint_to_decision_context.js.map +1 -0
  198. package/dist/database/migrations/20251027020000_update_agent_reusability.d.ts +21 -0
  199. package/dist/database/migrations/20251027020000_update_agent_reusability.d.ts.map +1 -0
  200. package/dist/database/migrations/20251027020000_update_agent_reusability.js +38 -0
  201. package/dist/database/migrations/20251027020000_update_agent_reusability.js.map +1 -0
  202. package/dist/database/migrations/20251028000000_simplify_agent_system.d.ts +26 -0
  203. package/dist/database/migrations/20251028000000_simplify_agent_system.d.ts.map +1 -0
  204. package/dist/database/migrations/20251028000000_simplify_agent_system.js +56 -0
  205. package/dist/database/migrations/20251028000000_simplify_agent_system.js.map +1 -0
  206. package/dist/database/migrations/20251031000000_drop_orphaned_message_view.d.ts +16 -0
  207. package/dist/database/migrations/20251031000000_drop_orphaned_message_view.d.ts.map +1 -0
  208. package/dist/database/migrations/20251031000000_drop_orphaned_message_view.js +52 -0
  209. package/dist/database/migrations/20251031000000_drop_orphaned_message_view.js.map +1 -0
  210. package/dist/database/migrations/20251104000000_add_multi_project_v3_7_0.d.ts +56 -0
  211. package/dist/database/migrations/20251104000000_add_multi_project_v3_7_0.d.ts.map +1 -0
  212. package/dist/database/migrations/20251104000000_add_multi_project_v3_7_0.js +701 -0
  213. package/dist/database/migrations/20251104000000_add_multi_project_v3_7_0.js.map +1 -0
  214. package/dist/database/migrations/20251104000003_rename_constraints_created_by_to_agent_id.d.ts +30 -0
  215. package/dist/database/migrations/20251104000003_rename_constraints_created_by_to_agent_id.d.ts.map +1 -0
  216. package/dist/database/migrations/20251104000003_rename_constraints_created_by_to_agent_id.js +180 -0
  217. package/dist/database/migrations/20251104000003_rename_constraints_created_by_to_agent_id.js.map +1 -0
  218. package/dist/database/migrations/20251105000000_add_token_usage_table.d.ts +19 -0
  219. package/dist/database/migrations/20251105000000_add_token_usage_table.d.ts.map +1 -0
  220. package/dist/database/migrations/20251105000000_add_token_usage_table.js +47 -0
  221. package/dist/database/migrations/20251105000000_add_token_usage_table.js.map +1 -0
  222. package/dist/database/migrations/20251105000001_rename_decision_context_decided_by_to_agent_id.d.ts +28 -0
  223. package/dist/database/migrations/20251105000001_rename_decision_context_decided_by_to_agent_id.d.ts.map +1 -0
  224. package/dist/database/migrations/20251105000001_rename_decision_context_decided_by_to_agent_id.js +123 -0
  225. package/dist/database/migrations/20251105000001_rename_decision_context_decided_by_to_agent_id.js.map +1 -0
  226. package/dist/database/migrations/20251106000000_fix_master_tables_project_id_v3_7_3.d.ts +36 -0
  227. package/dist/database/migrations/20251106000000_fix_master_tables_project_id_v3_7_3.d.ts.map +1 -0
  228. package/dist/database/migrations/20251106000000_fix_master_tables_project_id_v3_7_3.js +559 -0
  229. package/dist/database/migrations/20251106000000_fix_master_tables_project_id_v3_7_3.js.map +1 -0
  230. package/dist/database/migrations/20251108000000_add_planning_layers_v3_8_0.d.ts +26 -0
  231. package/dist/database/migrations/20251108000000_add_planning_layers_v3_8_0.d.ts.map +1 -0
  232. package/dist/database/migrations/20251108000000_add_planning_layers_v3_8_0.js +78 -0
  233. package/dist/database/migrations/20251108000000_add_planning_layers_v3_8_0.js.map +1 -0
  234. package/dist/database/migrations/20251108000000_hotfix_v_tagged_constraints_project_id.d.ts +17 -0
  235. package/dist/database/migrations/20251108000000_hotfix_v_tagged_constraints_project_id.d.ts.map +1 -0
  236. package/dist/database/migrations/20251108000000_hotfix_v_tagged_constraints_project_id.js +78 -0
  237. package/dist/database/migrations/20251108000000_hotfix_v_tagged_constraints_project_id.js.map +1 -0
  238. package/dist/database/migrations/20251109000000_fix_task_file_links_unique_constraint_v3_8_0.d.ts +24 -0
  239. package/dist/database/migrations/20251109000000_fix_task_file_links_unique_constraint_v3_8_0.d.ts.map +1 -0
  240. package/dist/database/migrations/20251109000000_fix_task_file_links_unique_constraint_v3_8_0.js +63 -0
  241. package/dist/database/migrations/20251109000000_fix_task_file_links_unique_constraint_v3_8_0.js.map +1 -0
  242. package/dist/database/migrations/20251109000002_multi_project_cross_db_compat_v3_7_5.d.ts +27 -0
  243. package/dist/database/migrations/20251109000002_multi_project_cross_db_compat_v3_7_5.d.ts.map +1 -0
  244. package/dist/database/migrations/20251109000002_multi_project_cross_db_compat_v3_7_5.js +276 -0
  245. package/dist/database/migrations/20251109000002_multi_project_cross_db_compat_v3_7_5.js.map +1 -0
  246. package/dist/database/migrations/20251109000003_token_usage_cross_db_compat_v3_7_5.d.ts +27 -0
  247. package/dist/database/migrations/20251109000003_token_usage_cross_db_compat_v3_7_5.d.ts.map +1 -0
  248. package/dist/database/migrations/20251109000003_token_usage_cross_db_compat_v3_7_5.js +67 -0
  249. package/dist/database/migrations/20251109000003_token_usage_cross_db_compat_v3_7_5.js.map +1 -0
  250. package/dist/database/migrations/20251109010000_tool_cleanup_v3_8_0.d.ts +32 -0
  251. package/dist/database/migrations/20251109010000_tool_cleanup_v3_8_0.d.ts.map +1 -0
  252. package/dist/database/migrations/20251109010000_tool_cleanup_v3_8_0.js +352 -0
  253. package/dist/database/migrations/20251109010000_tool_cleanup_v3_8_0.js.map +1 -0
  254. package/dist/database/migrations/20251109020000_fix_missing_help_actions_v3_8_0.d.ts +35 -0
  255. package/dist/database/migrations/20251109020000_fix_missing_help_actions_v3_8_0.d.ts.map +1 -0
  256. package/dist/database/migrations/20251109020000_fix_missing_help_actions_v3_8_0.js +237 -0
  257. package/dist/database/migrations/20251109020000_fix_missing_help_actions_v3_8_0.js.map +1 -0
  258. package/dist/database/migrations/20251111235959_preemptive_fix_cross_database_v3_9_0.d.ts +22 -0
  259. package/dist/database/migrations/20251111235959_preemptive_fix_cross_database_v3_9_0.d.ts.map +1 -0
  260. package/dist/database/migrations/20251111235959_preemptive_fix_cross_database_v3_9_0.js +190 -0
  261. package/dist/database/migrations/20251111235959_preemptive_fix_cross_database_v3_9_0.js.map +1 -0
  262. package/dist/database/migrations/20251112000000_decision_intelligence_v3_9_0.d.ts +32 -0
  263. package/dist/database/migrations/20251112000000_decision_intelligence_v3_9_0.d.ts.map +1 -0
  264. package/dist/database/migrations/20251112000000_decision_intelligence_v3_9_0.js +342 -0
  265. package/dist/database/migrations/20251112000000_decision_intelligence_v3_9_0.js.map +1 -0
  266. package/dist/database/migrations/20251112000001_fix_task_file_links_schema_v3_9_0.d.ts +25 -0
  267. package/dist/database/migrations/20251112000001_fix_task_file_links_schema_v3_9_0.d.ts.map +1 -0
  268. package/dist/database/migrations/20251112000001_fix_task_file_links_schema_v3_9_0.js +109 -0
  269. package/dist/database/migrations/20251112000001_fix_task_file_links_schema_v3_9_0.js.map +1 -0
  270. package/dist/database/migrations/20251112000002_fix_task_pruned_files_schema_v3_9_0.d.ts +24 -0
  271. package/dist/database/migrations/20251112000002_fix_task_pruned_files_schema_v3_9_0.d.ts.map +1 -0
  272. package/dist/database/migrations/20251112000002_fix_task_pruned_files_schema_v3_9_0.js +111 -0
  273. package/dist/database/migrations/20251112000002_fix_task_pruned_files_schema_v3_9_0.js.map +1 -0
  274. package/dist/database/migrations/20251114000000_fix_v_tagged_decisions_numeric_support.d.ts +24 -0
  275. package/dist/database/migrations/20251114000000_fix_v_tagged_decisions_numeric_support.d.ts.map +1 -0
  276. package/dist/database/migrations/20251114000000_fix_v_tagged_decisions_numeric_support.js +90 -0
  277. package/dist/database/migrations/20251114000000_fix_v_tagged_decisions_numeric_support.js.map +1 -0
  278. package/dist/database/migrations/20251114120000_add_suggest_tool_to_help_system_v3_9_0.d.ts +20 -0
  279. package/dist/database/migrations/20251114120000_add_suggest_tool_to_help_system_v3_9_0.d.ts.map +1 -0
  280. package/dist/database/migrations/20251114120000_add_suggest_tool_to_help_system_v3_9_0.js +275 -0
  281. package/dist/database/migrations/20251114120000_add_suggest_tool_to_help_system_v3_9_0.js.map +1 -0
  282. package/dist/database/migrations/20251114121000_add_suggest_tool_use_cases_v3_9_0.d.ts +20 -0
  283. package/dist/database/migrations/20251114121000_add_suggest_tool_use_cases_v3_9_0.d.ts.map +1 -0
  284. package/dist/database/migrations/20251114121000_add_suggest_tool_use_cases_v3_9_0.js +246 -0
  285. package/dist/database/migrations/20251114121000_add_suggest_tool_use_cases_v3_9_0.js.map +1 -0
  286. package/dist/database/migrations/20251114130000_seed_builtin_policies_v3_9_0.d.ts +23 -0
  287. package/dist/database/migrations/20251114130000_seed_builtin_policies_v3_9_0.d.ts.map +1 -0
  288. package/dist/database/migrations/20251114130000_seed_builtin_policies_v3_9_0.js +175 -0
  289. package/dist/database/migrations/20251114130000_seed_builtin_policies_v3_9_0.js.map +1 -0
  290. package/dist/database/migrations/20251114140000_add_policy_help_v3_9_0.d.ts +21 -0
  291. package/dist/database/migrations/20251114140000_add_policy_help_v3_9_0.d.ts.map +1 -0
  292. package/dist/database/migrations/20251114140000_add_policy_help_v3_9_0.js +235 -0
  293. package/dist/database/migrations/20251114140000_add_policy_help_v3_9_0.js.map +1 -0
  294. package/dist/database/migrations/20251114141000_add_policy_use_cases_v3_9_0.d.ts +21 -0
  295. package/dist/database/migrations/20251114141000_add_policy_use_cases_v3_9_0.d.ts.map +1 -0
  296. package/dist/database/migrations/20251114141000_add_policy_use_cases_v3_9_0.js +244 -0
  297. package/dist/database/migrations/20251114141000_add_policy_use_cases_v3_9_0.js.map +1 -0
  298. package/dist/database/migrations/20251114150000_fix_policy_unique_constraint_v3_9_0.d.ts +23 -0
  299. package/dist/database/migrations/20251114150000_fix_policy_unique_constraint_v3_9_0.d.ts.map +1 -0
  300. package/dist/database/migrations/20251114150000_fix_policy_unique_constraint_v3_9_0.js +70 -0
  301. package/dist/database/migrations/20251114150000_fix_policy_unique_constraint_v3_9_0.js.map +1 -0
  302. package/dist/database/migrations/20251115000000_fix_task_decision_links_unique_constraint.d.ts +29 -0
  303. package/dist/database/migrations/20251115000000_fix_task_decision_links_unique_constraint.d.ts.map +1 -0
  304. package/dist/database/migrations/20251115000000_fix_task_decision_links_unique_constraint.js +135 -0
  305. package/dist/database/migrations/20251115000000_fix_task_decision_links_unique_constraint.js.map +1 -0
  306. package/dist/database/migrations/20251115100000_fix_read_keyword_index_v3_9_0.d.ts +23 -0
  307. package/dist/database/migrations/20251115100000_fix_read_keyword_index_v3_9_0.d.ts.map +1 -0
  308. package/dist/database/migrations/20251115100000_fix_read_keyword_index_v3_9_0.js +42 -0
  309. package/dist/database/migrations/20251115100000_fix_read_keyword_index_v3_9_0.js.map +1 -0
  310. package/dist/database/migrations/20251115110000_fix_cross_database_timestamps_v3_9_0.d.ts +25 -0
  311. package/dist/database/migrations/20251115110000_fix_cross_database_timestamps_v3_9_0.d.ts.map +1 -0
  312. package/dist/database/migrations/20251115110000_fix_cross_database_timestamps_v3_9_0.js +102 -0
  313. package/dist/database/migrations/20251115110000_fix_cross_database_timestamps_v3_9_0.js.map +1 -0
  314. package/dist/database/migrations/20251115120000_fix_all_cross_db_issues_v3_9_0.d.ts +25 -0
  315. package/dist/database/migrations/20251115120000_fix_all_cross_db_issues_v3_9_0.d.ts.map +1 -0
  316. package/dist/database/migrations/20251115120000_fix_all_cross_db_issues_v3_9_0.js +55 -0
  317. package/dist/database/migrations/20251115120000_fix_all_cross_db_issues_v3_9_0.js.map +1 -0
  318. package/dist/database/migrations/20251118000000_eliminate_views_v3_9_0.d.ts +29 -0
  319. package/dist/database/migrations/20251118000000_eliminate_views_v3_9_0.d.ts.map +1 -0
  320. package/dist/database/migrations/20251118000000_eliminate_views_v3_9_0.js +62 -0
  321. package/dist/database/migrations/20251118000000_eliminate_views_v3_9_0.js.map +1 -0
  322. package/dist/database/migrations/20251119000000_add_constraint_text_hash_v3_9_1.d.ts +25 -0
  323. package/dist/database/migrations/20251119000000_add_constraint_text_hash_v3_9_1.d.ts.map +1 -0
  324. package/dist/database/migrations/20251119000000_add_constraint_text_hash_v3_9_1.js +100 -0
  325. package/dist/database/migrations/20251119000000_add_constraint_text_hash_v3_9_1.js.map +1 -0
  326. package/dist/init-commands.d.ts +7 -0
  327. package/dist/init-commands.d.ts.map +1 -0
  328. package/dist/init-commands.js +185 -0
  329. package/dist/init-commands.js.map +1 -0
  330. package/dist/schema.d.ts +11 -19
  331. package/dist/schema.d.ts.map +1 -1
  332. package/dist/schema.js +51 -63
  333. package/dist/schema.js.map +1 -1
  334. package/dist/server/tool-handlers.d.ts.map +1 -1
  335. package/dist/server/tool-handlers.js +20 -1
  336. package/dist/server/tool-handlers.js.map +1 -1
  337. package/dist/server/tool-registry.d.ts.map +1 -1
  338. package/dist/server/tool-registry.js +42 -1
  339. package/dist/server/tool-registry.js.map +1 -1
  340. package/dist/sync-commands.d.ts +13 -0
  341. package/dist/sync-commands.d.ts.map +1 -0
  342. package/dist/sync-commands.js +115 -0
  343. package/dist/sync-commands.js.map +1 -0
  344. package/dist/tests/database/connection/connection-manager-integration.test.d.ts.map +1 -0
  345. package/dist/tests/{connection-manager-integration.test.js → database/connection/connection-manager-integration.test.js} +1 -1
  346. package/dist/tests/database/connection/connection-manager-integration.test.js.map +1 -0
  347. package/dist/tests/database/connection/connection-manager.test.d.ts.map +1 -0
  348. package/dist/tests/{connection-manager.test.js → database/connection/connection-manager.test.js} +1 -1
  349. package/dist/tests/database/connection/connection-manager.test.js.map +1 -0
  350. package/dist/tests/database/migrations/idempotency.test.d.ts +2 -0
  351. package/dist/tests/database/migrations/idempotency.test.d.ts.map +1 -0
  352. package/dist/tests/{migration-idempotency.test.js → database/migrations/idempotency.test.js} +1 -1
  353. package/dist/tests/database/migrations/idempotency.test.js.map +1 -0
  354. package/dist/tests/database/migrations/upgrade-paths.test.d.ts +2 -0
  355. package/dist/tests/database/migrations/upgrade-paths.test.d.ts.map +1 -0
  356. package/dist/tests/{migration-upgrade-paths.test.js → database/migrations/upgrade-paths.test.js} +1 -1
  357. package/dist/tests/database/migrations/upgrade-paths.test.js.map +1 -0
  358. package/dist/tests/database/multi-project/multi-project.test.d.ts.map +1 -0
  359. package/dist/tests/{multi-project.test.js → database/multi-project/multi-project.test.js} +5 -5
  360. package/dist/tests/database/multi-project/multi-project.test.js.map +1 -0
  361. package/dist/tests/{sql-dump-converters.test.d.ts → database/sql-dump/converters.test.d.ts} +1 -1
  362. package/dist/tests/database/sql-dump/converters.test.d.ts.map +1 -0
  363. package/dist/tests/{sql-dump-converters.test.js → database/sql-dump/converters.test.js} +2 -2
  364. package/dist/tests/database/sql-dump/converters.test.js.map +1 -0
  365. package/dist/tests/{sql-dump-default-conversions.test.d.ts → database/sql-dump/default-conversions.test.d.ts} +1 -1
  366. package/dist/tests/database/sql-dump/default-conversions.test.d.ts.map +1 -0
  367. package/dist/tests/{sql-dump-default-conversions.test.js → database/sql-dump/default-conversions.test.js} +2 -2
  368. package/dist/tests/database/sql-dump/default-conversions.test.js.map +1 -0
  369. package/dist/tests/database/sql-dump/table-ordering.test.d.ts +27 -0
  370. package/dist/tests/database/sql-dump/table-ordering.test.d.ts.map +1 -0
  371. package/dist/tests/{sql-dump-table-ordering.test.js → database/sql-dump/table-ordering.test.js} +34 -8
  372. package/dist/tests/database/sql-dump/table-ordering.test.js.map +1 -0
  373. package/dist/tests/database/sql-dump/type-conversion.test.d.ts.map +1 -0
  374. package/dist/tests/{type-conversion.test.js → database/sql-dump/type-conversion.test.js} +1 -1
  375. package/dist/tests/database/sql-dump/type-conversion.test.js.map +1 -0
  376. package/dist/tests/database/testing-config.d.ts +105 -0
  377. package/dist/tests/database/testing-config.d.ts.map +1 -0
  378. package/dist/tests/database/testing-config.js +192 -0
  379. package/dist/tests/database/testing-config.js.map +1 -0
  380. package/dist/tests/{sql-dump-cross-database.test.d.ts → docker/cross-database.test.d.ts} +1 -1
  381. package/dist/tests/docker/cross-database.test.d.ts.map +1 -0
  382. package/dist/tests/{sql-dump-cross-database.test.js → docker/cross-database.test.js} +3 -3
  383. package/dist/tests/docker/cross-database.test.js.map +1 -0
  384. package/dist/tests/docker/dump-import.test.d.ts.map +1 -0
  385. package/dist/tests/{dump-import.test.js → docker/dump-import.test.js} +25 -31
  386. package/dist/tests/docker/dump-import.test.js.map +1 -0
  387. package/dist/tests/{sql-dump-fk-constraints.test.d.ts → docker/fk-constraints.test.d.ts} +1 -1
  388. package/dist/tests/docker/fk-constraints.test.d.ts.map +1 -0
  389. package/dist/tests/{sql-dump-fk-constraints.test.js → docker/fk-constraints.test.js} +3 -3
  390. package/dist/tests/docker/fk-constraints.test.js.map +1 -0
  391. package/dist/tests/{sql-dump-indexes.test.d.ts → docker/indexes.test.d.ts} +1 -1
  392. package/dist/tests/docker/indexes.test.d.ts.map +1 -0
  393. package/dist/tests/{sql-dump-indexes.test.js → docker/indexes.test.js} +10 -29
  394. package/dist/tests/docker/indexes.test.js.map +1 -0
  395. package/dist/tests/{sql-dump-integration.test.d.ts → docker/integration.test.d.ts} +1 -1
  396. package/dist/tests/docker/integration.test.d.ts.map +1 -0
  397. package/dist/tests/{sql-dump-integration.test.js → docker/integration.test.js} +9 -28
  398. package/dist/tests/docker/integration.test.js.map +1 -0
  399. package/dist/tests/docker/multi-project-migration.test.d.ts.map +1 -0
  400. package/dist/tests/{multi-project-migration.test.js → docker/multi-project-migration.test.js} +20 -8
  401. package/dist/tests/docker/multi-project-migration.test.js.map +1 -0
  402. package/dist/tests/docker/native/constraint-operations.test.d.ts +23 -0
  403. package/dist/tests/docker/native/constraint-operations.test.d.ts.map +1 -0
  404. package/dist/tests/docker/native/constraint-operations.test.js +693 -0
  405. package/dist/tests/docker/native/constraint-operations.test.js.map +1 -0
  406. package/dist/tests/docker/native/db-init.d.ts +59 -0
  407. package/dist/tests/docker/native/db-init.d.ts.map +1 -0
  408. package/dist/tests/docker/native/db-init.js +207 -0
  409. package/dist/tests/docker/native/db-init.js.map +1 -0
  410. package/dist/tests/docker/native/decision-operations.test.d.ts +16 -0
  411. package/dist/tests/docker/native/decision-operations.test.d.ts.map +1 -0
  412. package/dist/tests/docker/native/decision-operations.test.js +590 -0
  413. package/dist/tests/docker/native/decision-operations.test.js.map +1 -0
  414. package/dist/tests/docker/native/help-system.test.d.ts +10 -0
  415. package/dist/tests/docker/native/help-system.test.d.ts.map +1 -0
  416. package/dist/tests/docker/native/help-system.test.js +568 -0
  417. package/dist/tests/docker/native/help-system.test.js.map +1 -0
  418. package/dist/tests/docker/native/suggest-tool.test.d.ts +16 -0
  419. package/dist/tests/docker/native/suggest-tool.test.d.ts.map +1 -0
  420. package/dist/tests/docker/native/suggest-tool.test.js +607 -0
  421. package/dist/tests/docker/native/suggest-tool.test.js.map +1 -0
  422. package/dist/tests/docker/native/task-operations.test.d.ts +16 -0
  423. package/dist/tests/docker/native/task-operations.test.d.ts.map +1 -0
  424. package/dist/tests/docker/native/task-operations.test.js +836 -0
  425. package/dist/tests/docker/native/task-operations.test.js.map +1 -0
  426. package/dist/tests/docker/native/test-harness.d.ts +129 -0
  427. package/dist/tests/docker/native/test-harness.d.ts.map +1 -0
  428. package/dist/tests/docker/native/test-harness.js +314 -0
  429. package/dist/tests/docker/native/test-harness.js.map +1 -0
  430. package/dist/tests/docker/schema-migration.test.d.ts.map +1 -0
  431. package/dist/tests/{schema-migration.test.js → docker/schema-migration.test.js} +8 -18
  432. package/dist/tests/docker/schema-migration.test.js.map +1 -0
  433. package/dist/tests/feature/decision/analytics.test.d.ts +7 -0
  434. package/dist/tests/feature/decision/analytics.test.d.ts.map +1 -0
  435. package/dist/tests/feature/decision/analytics.test.js +140 -0
  436. package/dist/tests/feature/decision/analytics.test.js.map +1 -0
  437. package/dist/tests/feature/decision/batch-validation-comprehensive.test.d.ts.map +1 -0
  438. package/dist/tests/{batch-validation-comprehensive.test.js → feature/decision/batch-validation-comprehensive.test.js} +5 -5
  439. package/dist/tests/feature/decision/batch-validation-comprehensive.test.js.map +1 -0
  440. package/dist/tests/feature/decision/batch-validation-integration.test.d.ts.map +1 -0
  441. package/dist/tests/{batch-validation-integration.test.js → feature/decision/batch-validation-integration.test.js} +3 -3
  442. package/dist/tests/feature/decision/batch-validation-integration.test.js.map +1 -0
  443. package/dist/tests/{decision-batch-validation.test.d.ts → feature/decision/batch-validation.test.d.ts} +1 -1
  444. package/dist/tests/feature/decision/batch-validation.test.d.ts.map +1 -0
  445. package/dist/tests/{decision-batch-validation.test.js → feature/decision/batch-validation.test.js} +4 -4
  446. package/dist/tests/feature/decision/batch-validation.test.js.map +1 -0
  447. package/dist/tests/feature/decision/context-modular.test.d.ts.map +1 -0
  448. package/dist/tests/{context-modular.test.js → feature/decision/context-modular.test.js} +17 -8
  449. package/dist/tests/feature/decision/context-modular.test.js.map +1 -0
  450. package/dist/tests/feature/help/help-system.test.d.ts.map +1 -0
  451. package/dist/tests/{help-system.test.js → feature/help/help-system.test.js} +9 -9
  452. package/dist/tests/feature/help/help-system.test.js.map +1 -0
  453. package/dist/tests/{tasks.auto-pruning-decision-link.test.d.ts → feature/task/auto-pruning-decision-link.test.d.ts} +1 -1
  454. package/dist/tests/feature/task/auto-pruning-decision-link.test.d.ts.map +1 -0
  455. package/dist/tests/{tasks.auto-pruning-decision-link.test.js → feature/task/auto-pruning-decision-link.test.js} +30 -8
  456. package/dist/tests/feature/task/auto-pruning-decision-link.test.js.map +1 -0
  457. package/dist/tests/{tasks.auto-pruning-partial.test.d.ts → feature/task/auto-pruning-partial.test.d.ts} +1 -1
  458. package/dist/tests/feature/task/auto-pruning-partial.test.d.ts.map +1 -0
  459. package/dist/tests/{tasks.auto-pruning-partial.test.js → feature/task/auto-pruning-partial.test.js} +26 -4
  460. package/dist/tests/feature/task/auto-pruning-partial.test.js.map +1 -0
  461. package/dist/tests/{tasks.auto-pruning-persistence.test.d.ts → feature/task/auto-pruning-persistence.test.d.ts} +1 -1
  462. package/dist/tests/feature/task/auto-pruning-persistence.test.d.ts.map +1 -0
  463. package/dist/tests/{tasks.auto-pruning-persistence.test.js → feature/task/auto-pruning-persistence.test.js} +23 -3
  464. package/dist/tests/feature/task/auto-pruning-persistence.test.js.map +1 -0
  465. package/dist/tests/{tasks.auto-pruning-safety.test.d.ts → feature/task/auto-pruning-safety.test.d.ts} +1 -1
  466. package/dist/tests/feature/task/auto-pruning-safety.test.d.ts.map +1 -0
  467. package/dist/tests/{tasks.auto-pruning-safety.test.js → feature/task/auto-pruning-safety.test.js} +46 -20
  468. package/dist/tests/feature/task/auto-pruning-safety.test.js.map +1 -0
  469. package/dist/tests/{tasks.dependencies.test.d.ts → feature/task/dependencies.test.d.ts} +1 -1
  470. package/dist/tests/feature/task/dependencies.test.d.ts.map +1 -0
  471. package/dist/tests/{tasks.dependencies.test.js → feature/task/dependencies.test.js} +46 -30
  472. package/dist/tests/feature/task/dependencies.test.js.map +1 -0
  473. package/dist/tests/{tasks.file-actions-integration.test.d.ts → feature/task/file-actions-integration.test.d.ts} +1 -1
  474. package/dist/tests/feature/task/file-actions-integration.test.d.ts.map +1 -0
  475. package/dist/tests/{tasks.file-actions-integration.test.js → feature/task/file-actions-integration.test.js} +6 -6
  476. package/dist/tests/feature/task/file-actions-integration.test.js.map +1 -0
  477. package/dist/tests/{tasks.file-actions-validation.test.d.ts → feature/task/file-actions-validation.test.d.ts} +1 -1
  478. package/dist/tests/feature/task/file-actions-validation.test.d.ts.map +1 -0
  479. package/dist/tests/{tasks.file-actions-validation.test.js → feature/task/file-actions-validation.test.js} +11 -4
  480. package/dist/tests/feature/task/file-actions-validation.test.js.map +1 -0
  481. package/dist/tests/{tasks.link-file-backward-compat.test.d.ts → feature/task/link-file-backward-compat.test.d.ts} +1 -1
  482. package/dist/tests/feature/task/link-file-backward-compat.test.d.ts.map +1 -0
  483. package/dist/tests/{tasks.link-file-backward-compat.test.js → feature/task/link-file-backward-compat.test.js} +65 -40
  484. package/dist/tests/feature/task/link-file-backward-compat.test.js.map +1 -0
  485. package/dist/tests/{tasks.watch-files-action.test.d.ts → feature/task/watch-files-action.test.d.ts} +3 -1
  486. package/dist/tests/feature/task/watch-files-action.test.d.ts.map +1 -0
  487. package/dist/tests/{tasks.watch-files-action.test.js → feature/task/watch-files-action.test.js} +58 -36
  488. package/dist/tests/feature/task/watch-files-action.test.js.map +1 -0
  489. package/dist/tests/{tasks.watch-files-parameter.test.d.ts → feature/task/watch-files-parameter.test.d.ts} +3 -1
  490. package/dist/tests/feature/task/watch-files-parameter.test.d.ts.map +1 -0
  491. package/dist/tests/{tasks.watch-files-parameter.test.js → feature/task/watch-files-parameter.test.js} +64 -39
  492. package/dist/tests/feature/task/watch-files-parameter.test.js.map +1 -0
  493. package/dist/tests/feature/vcs/git-aware-completion.test.d.ts.map +1 -0
  494. package/dist/tests/{git-aware-completion.test.js → feature/vcs/git-aware-completion.test.js} +25 -11
  495. package/dist/tests/feature/vcs/git-aware-completion.test.js.map +1 -0
  496. package/dist/tests/feature/vcs/two-step-git-completion.test.d.ts.map +1 -0
  497. package/dist/tests/{two-step-git-completion.test.js → feature/vcs/two-step-git-completion.test.js} +2 -2
  498. package/dist/tests/feature/vcs/two-step-git-completion.test.js.map +1 -0
  499. package/dist/tests/feature/vcs/vcs-staging.test.d.ts.map +1 -0
  500. package/dist/tests/{vcs-staging.test.js → feature/vcs/vcs-staging.test.js} +8 -3
  501. package/dist/tests/feature/vcs/vcs-staging.test.js.map +1 -0
  502. package/dist/tests/{all-features.test.d.ts → integration/all-features.standalone.d.ts} +1 -1
  503. package/dist/tests/integration/all-features.standalone.d.ts.map +1 -0
  504. package/dist/tests/{all-features.test.js → integration/all-features.standalone.js} +7 -9
  505. package/dist/tests/integration/all-features.standalone.js.map +1 -0
  506. package/dist/tests/integration/auto-trigger-suggestions.test.d.ts +7 -0
  507. package/dist/tests/integration/auto-trigger-suggestions.test.d.ts.map +1 -0
  508. package/dist/tests/integration/auto-trigger-suggestions.test.js +331 -0
  509. package/dist/tests/integration/auto-trigger-suggestions.test.js.map +1 -0
  510. package/dist/tests/integration/decision-intelligence-e2e.test.d.ts +13 -0
  511. package/dist/tests/integration/decision-intelligence-e2e.test.d.ts.map +1 -0
  512. package/dist/tests/integration/decision-intelligence-e2e.test.js +558 -0
  513. package/dist/tests/integration/decision-intelligence-e2e.test.js.map +1 -0
  514. package/dist/tests/integration/e2e-workflow1-debug.test.d.ts +5 -0
  515. package/dist/tests/integration/e2e-workflow1-debug.test.d.ts.map +1 -0
  516. package/dist/tests/integration/e2e-workflow1-debug.test.js +99 -0
  517. package/dist/tests/integration/e2e-workflow1-debug.test.js.map +1 -0
  518. package/dist/tests/integration/hybrid-similarity-detection.test.d.ts +7 -0
  519. package/dist/tests/integration/hybrid-similarity-detection.test.d.ts.map +1 -0
  520. package/dist/tests/integration/hybrid-similarity-detection.test.js +512 -0
  521. package/dist/tests/integration/hybrid-similarity-detection.test.js.map +1 -0
  522. package/dist/tests/integration/suggest-simple.test.d.ts +5 -0
  523. package/dist/tests/integration/suggest-simple.test.d.ts.map +1 -0
  524. package/dist/tests/integration/suggest-simple.test.js +72 -0
  525. package/dist/tests/integration/suggest-simple.test.js.map +1 -0
  526. package/dist/tests/unit/universal-knex.test.d.ts +2 -0
  527. package/dist/tests/unit/universal-knex.test.d.ts.map +1 -0
  528. package/dist/tests/unit/universal-knex.test.js +250 -0
  529. package/dist/tests/unit/universal-knex.test.js.map +1 -0
  530. package/dist/tests/unit/utils/config-loader.test.d.ts.map +1 -0
  531. package/dist/tests/{config-loader.test.js → unit/utils/config-loader.test.js} +63 -42
  532. package/dist/tests/unit/utils/config-loader.test.js.map +1 -0
  533. package/dist/tests/unit/utils/project-detector.test.d.ts.map +1 -0
  534. package/dist/tests/{project-detector.test.js → unit/utils/project-detector.test.js} +1 -1
  535. package/dist/tests/unit/utils/project-detector.test.js.map +1 -0
  536. package/dist/tests/unit/utils/semver.test.d.ts +2 -0
  537. package/dist/tests/unit/utils/semver.test.d.ts.map +1 -0
  538. package/dist/tests/unit/utils/semver.test.js +72 -0
  539. package/dist/tests/unit/utils/semver.test.js.map +1 -0
  540. package/dist/tests/unit/validation/batch-validation.test.d.ts.map +1 -0
  541. package/dist/tests/{batch-validation.test.js → unit/validation/batch-validation.test.js} +2 -2
  542. package/dist/tests/unit/validation/batch-validation.test.js.map +1 -0
  543. package/dist/tests/unit/validation/parameter-validation.test.d.ts.map +1 -0
  544. package/dist/tests/{parameter-validation.test.js → unit/validation/parameter-validation.test.js} +9 -12
  545. package/dist/tests/unit/validation/parameter-validation.test.js.map +1 -0
  546. package/dist/tests/unit/validation/policy-validation.test.d.ts +15 -0
  547. package/dist/tests/unit/validation/policy-validation.test.d.ts.map +1 -0
  548. package/dist/tests/unit/validation/policy-validation.test.js +343 -0
  549. package/dist/tests/unit/validation/policy-validation.test.js.map +1 -0
  550. package/dist/tests/utils/db-config.d.ts +21 -0
  551. package/dist/tests/utils/db-config.d.ts.map +1 -0
  552. package/dist/tests/utils/db-config.js +59 -0
  553. package/dist/tests/utils/db-config.js.map +1 -0
  554. package/dist/tests/utils/db-import.d.ts +11 -0
  555. package/dist/tests/utils/db-import.d.ts.map +1 -0
  556. package/dist/tests/utils/db-import.js +38 -0
  557. package/dist/tests/utils/db-import.js.map +1 -0
  558. package/dist/tests/utils/db-schema.d.ts +58 -0
  559. package/dist/tests/utils/db-schema.d.ts.map +1 -0
  560. package/dist/tests/utils/db-schema.js +218 -0
  561. package/dist/tests/utils/db-schema.js.map +1 -0
  562. package/dist/tests/utils/db-seeding.d.ts +18 -0
  563. package/dist/tests/utils/db-seeding.d.ts.map +1 -0
  564. package/dist/tests/utils/db-seeding.js +54 -0
  565. package/dist/tests/utils/db-seeding.js.map +1 -0
  566. package/dist/tests/utils/index.d.ts +20 -0
  567. package/dist/tests/utils/index.d.ts.map +1 -0
  568. package/dist/tests/utils/index.js +26 -0
  569. package/dist/tests/utils/index.js.map +1 -0
  570. package/dist/tests/utils/task-helpers.d.ts +67 -0
  571. package/dist/tests/utils/task-helpers.d.ts.map +1 -0
  572. package/dist/tests/utils/task-helpers.js +151 -0
  573. package/dist/tests/utils/task-helpers.js.map +1 -0
  574. package/dist/tests/utils/test-helpers.d.ts +93 -1
  575. package/dist/tests/utils/test-helpers.d.ts.map +1 -1
  576. package/dist/tests/utils/test-helpers.js +232 -64
  577. package/dist/tests/utils/test-helpers.js.map +1 -1
  578. package/dist/tests/utils/test-lifecycle.d.ts +52 -0
  579. package/dist/tests/utils/test-lifecycle.d.ts.map +1 -0
  580. package/dist/tests/utils/test-lifecycle.js +88 -0
  581. package/dist/tests/utils/test-lifecycle.js.map +1 -0
  582. package/dist/tools/context/actions/analytics.d.ts +88 -0
  583. package/dist/tools/context/actions/analytics.d.ts.map +1 -0
  584. package/dist/tools/context/actions/analytics.js +92 -0
  585. package/dist/tools/context/actions/analytics.js.map +1 -0
  586. package/dist/tools/context/actions/create-policy.d.ts +38 -0
  587. package/dist/tools/context/actions/create-policy.d.ts.map +1 -0
  588. package/dist/tools/context/actions/create-policy.js +87 -0
  589. package/dist/tools/context/actions/create-policy.js.map +1 -0
  590. package/dist/tools/context/actions/create-template.js +2 -2
  591. package/dist/tools/context/actions/create-template.js.map +1 -1
  592. package/dist/tools/context/actions/get.d.ts.map +1 -1
  593. package/dist/tools/context/actions/get.js +5 -4
  594. package/dist/tools/context/actions/get.js.map +1 -1
  595. package/dist/tools/context/actions/has-updates.d.ts.map +1 -1
  596. package/dist/tools/context/actions/has-updates.js +4 -19
  597. package/dist/tools/context/actions/has-updates.js.map +1 -1
  598. package/dist/tools/context/actions/list-policies.d.ts +31 -0
  599. package/dist/tools/context/actions/list-policies.d.ts.map +1 -0
  600. package/dist/tools/context/actions/list-policies.js +55 -0
  601. package/dist/tools/context/actions/list-policies.js.map +1 -0
  602. package/dist/tools/context/actions/list-templates.d.ts.map +1 -1
  603. package/dist/tools/context/actions/list-templates.js +2 -1
  604. package/dist/tools/context/actions/list-templates.js.map +1 -1
  605. package/dist/tools/context/actions/list.d.ts +1 -1
  606. package/dist/tools/context/actions/list.d.ts.map +1 -1
  607. package/dist/tools/context/actions/list.js +24 -18
  608. package/dist/tools/context/actions/list.js.map +1 -1
  609. package/dist/tools/context/actions/search-advanced.d.ts.map +1 -1
  610. package/dist/tools/context/actions/search-advanced.js +61 -42
  611. package/dist/tools/context/actions/search-advanced.js.map +1 -1
  612. package/dist/tools/context/actions/search-layer.d.ts.map +1 -1
  613. package/dist/tools/context/actions/search-layer.js +16 -7
  614. package/dist/tools/context/actions/search-layer.js.map +1 -1
  615. package/dist/tools/context/actions/search-tags.d.ts.map +1 -1
  616. package/dist/tools/context/actions/search-tags.js +22 -14
  617. package/dist/tools/context/actions/search-tags.js.map +1 -1
  618. package/dist/tools/context/actions/set-from-policy.d.ts +28 -0
  619. package/dist/tools/context/actions/set-from-policy.d.ts.map +1 -0
  620. package/dist/tools/context/actions/set-from-policy.js +54 -0
  621. package/dist/tools/context/actions/set-from-policy.js.map +1 -0
  622. package/dist/tools/context/actions/set-from-template.d.ts.map +1 -1
  623. package/dist/tools/context/actions/set-from-template.js +2 -1
  624. package/dist/tools/context/actions/set-from-template.js.map +1 -1
  625. package/dist/tools/context/index.d.ts +5 -0
  626. package/dist/tools/context/index.d.ts.map +1 -1
  627. package/dist/tools/context/index.js +5 -0
  628. package/dist/tools/context/index.js.map +1 -1
  629. package/dist/tools/context/internal/queries.d.ts.map +1 -1
  630. package/dist/tools/context/internal/queries.js +551 -31
  631. package/dist/tools/context/internal/queries.js.map +1 -1
  632. package/dist/tools/context/internal/validation.d.ts +4 -0
  633. package/dist/tools/context/internal/validation.d.ts.map +1 -1
  634. package/dist/tools/context/internal/validation.js +13 -0
  635. package/dist/tools/context/internal/validation.js.map +1 -1
  636. package/dist/tools/help/actions/query-action.js +1 -1
  637. package/dist/tools/help/actions/query-action.js.map +1 -1
  638. package/dist/tools/help/actions/query-params.js +1 -1
  639. package/dist/tools/help/actions/query-params.js.map +1 -1
  640. package/dist/tools/help/actions/query-tool.js +1 -1
  641. package/dist/tools/help/actions/query-tool.js.map +1 -1
  642. package/dist/tools/help-queries.d.ts +12 -12
  643. package/dist/tools/help-queries.d.ts.map +1 -1
  644. package/dist/tools/help-queries.js +121 -140
  645. package/dist/tools/help-queries.js.map +1 -1
  646. package/dist/tools/suggest/actions/by-context.d.ts +28 -0
  647. package/dist/tools/suggest/actions/by-context.d.ts.map +1 -0
  648. package/dist/tools/suggest/actions/by-context.js +68 -0
  649. package/dist/tools/suggest/actions/by-context.js.map +1 -0
  650. package/dist/tools/suggest/actions/by-key.d.ts +20 -0
  651. package/dist/tools/suggest/actions/by-key.d.ts.map +1 -0
  652. package/dist/tools/suggest/actions/by-key.js +55 -0
  653. package/dist/tools/suggest/actions/by-key.js.map +1 -0
  654. package/dist/tools/suggest/actions/by-tags.d.ts +23 -0
  655. package/dist/tools/suggest/actions/by-tags.d.ts.map +1 -0
  656. package/dist/tools/suggest/actions/by-tags.js +58 -0
  657. package/dist/tools/suggest/actions/by-tags.js.map +1 -0
  658. package/dist/tools/suggest/actions/check-duplicate.d.ts +20 -0
  659. package/dist/tools/suggest/actions/check-duplicate.d.ts.map +1 -0
  660. package/dist/tools/suggest/actions/check-duplicate.js +59 -0
  661. package/dist/tools/suggest/actions/check-duplicate.js.map +1 -0
  662. package/dist/tools/suggest/help/help.d.ts +5 -0
  663. package/dist/tools/suggest/help/help.d.ts.map +1 -0
  664. package/dist/tools/suggest/help/help.js +50 -0
  665. package/dist/tools/suggest/help/help.js.map +1 -0
  666. package/dist/tools/suggest/index.d.ts +18 -0
  667. package/dist/tools/suggest/index.d.ts.map +1 -0
  668. package/dist/tools/suggest/index.js +55 -0
  669. package/dist/tools/suggest/index.js.map +1 -0
  670. package/dist/tools/suggest/internal/queries.d.ts +60 -0
  671. package/dist/tools/suggest/internal/queries.d.ts.map +1 -0
  672. package/dist/tools/suggest/internal/queries.js +154 -0
  673. package/dist/tools/suggest/internal/queries.js.map +1 -0
  674. package/dist/tools/suggest/types.d.ts +70 -0
  675. package/dist/tools/suggest/types.d.ts.map +1 -0
  676. package/dist/tools/suggest/types.js +5 -0
  677. package/dist/tools/suggest/types.js.map +1 -0
  678. package/dist/tools/tasks/actions/link-pruned-file.d.ts +1 -0
  679. package/dist/tools/tasks/actions/link-pruned-file.d.ts.map +1 -1
  680. package/dist/tools/tasks/actions/link-pruned-file.js +7 -2
  681. package/dist/tools/tasks/actions/link-pruned-file.js.map +1 -1
  682. package/dist/tools/tasks/actions/link.d.ts.map +1 -1
  683. package/dist/tools/tasks/actions/link.js +4 -2
  684. package/dist/tools/tasks/actions/link.js.map +1 -1
  685. package/dist/tools/tasks/actions/list.d.ts.map +1 -1
  686. package/dist/tools/tasks/actions/list.js +37 -35
  687. package/dist/tools/tasks/actions/list.js.map +1 -1
  688. package/dist/tools/use_case/actions/search.d.ts +1 -1
  689. package/dist/tools/use_case/actions/search.d.ts.map +1 -1
  690. package/dist/tools/use_case/actions/search.js +31 -40
  691. package/dist/tools/use_case/actions/search.js.map +1 -1
  692. package/dist/types/actions.d.ts +10 -0
  693. package/dist/types/actions.d.ts.map +1 -1
  694. package/dist/types/decision/params.d.ts +7 -0
  695. package/dist/types/decision/params.d.ts.map +1 -1
  696. package/dist/types/decision/responses.d.ts +38 -0
  697. package/dist/types/decision/responses.d.ts.map +1 -1
  698. package/dist/types/view-entities.d.ts +1 -0
  699. package/dist/types/view-entities.d.ts.map +1 -1
  700. package/dist/types.d.ts +33 -1
  701. package/dist/types.d.ts.map +1 -1
  702. package/dist/utils/action-specs/decision-specs.js +3 -3
  703. package/dist/utils/action-specs/decision-specs.js.map +1 -1
  704. package/dist/utils/activity-logging.d.ts.map +1 -1
  705. package/dist/utils/activity-logging.js +7 -0
  706. package/dist/utils/activity-logging.js.map +1 -1
  707. package/dist/utils/db-aggregations.d.ts +88 -0
  708. package/dist/utils/db-aggregations.d.ts.map +1 -0
  709. package/dist/utils/db-aggregations.js +158 -0
  710. package/dist/utils/db-aggregations.js.map +1 -0
  711. package/dist/utils/file-pruning.d.ts +37 -13
  712. package/dist/utils/file-pruning.d.ts.map +1 -1
  713. package/dist/utils/file-pruning.js +93 -84
  714. package/dist/utils/file-pruning.js.map +1 -1
  715. package/dist/utils/policy-validator.d.ts +37 -0
  716. package/dist/utils/policy-validator.d.ts.map +1 -0
  717. package/dist/utils/policy-validator.js +240 -0
  718. package/dist/utils/policy-validator.js.map +1 -0
  719. package/dist/utils/quality-checks.d.ts +7 -7
  720. package/dist/utils/quality-checks.d.ts.map +1 -1
  721. package/dist/utils/quality-checks.js +18 -21
  722. package/dist/utils/quality-checks.js.map +1 -1
  723. package/dist/utils/semver.d.ts +50 -0
  724. package/dist/utils/semver.d.ts.map +1 -0
  725. package/dist/utils/semver.js +78 -0
  726. package/dist/utils/semver.js.map +1 -0
  727. package/dist/utils/sql-dump/schema/tables.d.ts.map +1 -1
  728. package/dist/utils/sql-dump/schema/tables.js +125 -7
  729. package/dist/utils/sql-dump/schema/tables.js.map +1 -1
  730. package/dist/utils/sql-dump/schema/views.d.ts.map +1 -1
  731. package/dist/utils/sql-dump/schema/views.js +6 -0
  732. package/dist/utils/sql-dump/schema/views.js.map +1 -1
  733. package/dist/utils/suggestion-scorer.d.ts +62 -0
  734. package/dist/utils/suggestion-scorer.d.ts.map +1 -0
  735. package/dist/utils/suggestion-scorer.js +169 -0
  736. package/dist/utils/suggestion-scorer.js.map +1 -0
  737. package/dist/utils/tag-parser.d.ts +52 -0
  738. package/dist/utils/tag-parser.d.ts.map +1 -0
  739. package/dist/utils/tag-parser.js +65 -0
  740. package/dist/utils/tag-parser.js.map +1 -0
  741. package/dist/utils/task-stale-detection.d.ts.map +1 -1
  742. package/dist/utils/task-stale-detection.js +40 -4
  743. package/dist/utils/task-stale-detection.js.map +1 -1
  744. package/dist/utils/token-logging.d.ts +9 -9
  745. package/dist/utils/token-logging.d.ts.map +1 -1
  746. package/dist/utils/token-logging.js +36 -38
  747. package/dist/utils/token-logging.js.map +1 -1
  748. package/dist/utils/universal-knex.d.ts +169 -0
  749. package/dist/utils/universal-knex.d.ts.map +1 -0
  750. package/dist/utils/universal-knex.js +318 -0
  751. package/dist/utils/universal-knex.js.map +1 -0
  752. package/dist/utils/validators.d.ts +2 -2
  753. package/dist/utils/validators.d.ts.map +1 -1
  754. package/dist/utils/validators.js +3 -2
  755. package/dist/utils/validators.js.map +1 -1
  756. package/dist/utils/vcs-adapter.d.ts.map +1 -1
  757. package/dist/utils/vcs-adapter.js +21 -14
  758. package/dist/utils/vcs-adapter.js.map +1 -1
  759. package/dist/utils/view-queries.d.ts +11 -3
  760. package/dist/utils/view-queries.d.ts.map +1 -1
  761. package/dist/utils/view-queries.js +122 -87
  762. package/dist/utils/view-queries.js.map +1 -1
  763. package/dist/watcher/file-watcher.d.ts.map +1 -1
  764. package/dist/watcher/file-watcher.js +99 -84
  765. package/dist/watcher/file-watcher.js.map +1 -1
  766. package/docs/BEST_PRACTICES.md +10 -0
  767. package/docs/DECISION_CONTEXT.md +190 -1
  768. package/docs/DECISION_INTELLIGENCE.md +594 -0
  769. package/docs/MIGRATION_GUIDE_V3.9.0.md +371 -0
  770. package/docs/SLASH_COMMANDS.md +652 -0
  771. package/docs/TOOL_REFERENCE.md +164 -22
  772. package/docs/TOOL_SELECTION.md +16 -2
  773. package/docs/WORKFLOWS.md +163 -0
  774. package/docs/changelogs/CHANGELOG_ARCHIVE_v3.4_and_older.md +296 -0
  775. package/package.json +35 -10
  776. package/scripts/check-cross-db-patterns.sh +105 -0
  777. package/scripts/filter-test-output.js +74 -0
  778. package/scripts/verify-migrations.sh +129 -0
  779. package/dist/tests/all-features.test.d.ts.map +0 -1
  780. package/dist/tests/all-features.test.js.map +0 -1
  781. package/dist/tests/batch-validation-comprehensive.test.d.ts.map +0 -1
  782. package/dist/tests/batch-validation-comprehensive.test.js.map +0 -1
  783. package/dist/tests/batch-validation-integration.test.d.ts.map +0 -1
  784. package/dist/tests/batch-validation-integration.test.js.map +0 -1
  785. package/dist/tests/batch-validation.test.d.ts.map +0 -1
  786. package/dist/tests/batch-validation.test.js.map +0 -1
  787. package/dist/tests/config-loader.test.d.ts.map +0 -1
  788. package/dist/tests/config-loader.test.js.map +0 -1
  789. package/dist/tests/connection-manager-integration.test.d.ts.map +0 -1
  790. package/dist/tests/connection-manager-integration.test.js.map +0 -1
  791. package/dist/tests/connection-manager.test.d.ts.map +0 -1
  792. package/dist/tests/connection-manager.test.js.map +0 -1
  793. package/dist/tests/context-modular.test.d.ts.map +0 -1
  794. package/dist/tests/context-modular.test.js.map +0 -1
  795. package/dist/tests/decision-batch-validation.test.d.ts.map +0 -1
  796. package/dist/tests/decision-batch-validation.test.js.map +0 -1
  797. package/dist/tests/dump-import.test.d.ts.map +0 -1
  798. package/dist/tests/dump-import.test.js.map +0 -1
  799. package/dist/tests/git-aware-completion.test.d.ts.map +0 -1
  800. package/dist/tests/git-aware-completion.test.js.map +0 -1
  801. package/dist/tests/help-system.test.d.ts.map +0 -1
  802. package/dist/tests/help-system.test.js.map +0 -1
  803. package/dist/tests/migration-idempotency.test.d.ts +0 -2
  804. package/dist/tests/migration-idempotency.test.d.ts.map +0 -1
  805. package/dist/tests/migration-idempotency.test.js.map +0 -1
  806. package/dist/tests/migration-upgrade-paths.test.d.ts +0 -2
  807. package/dist/tests/migration-upgrade-paths.test.d.ts.map +0 -1
  808. package/dist/tests/migration-upgrade-paths.test.js.map +0 -1
  809. package/dist/tests/multi-project-migration.test.d.ts.map +0 -1
  810. package/dist/tests/multi-project-migration.test.js.map +0 -1
  811. package/dist/tests/multi-project.test.d.ts.map +0 -1
  812. package/dist/tests/multi-project.test.js.map +0 -1
  813. package/dist/tests/parameter-validation.test.d.ts.map +0 -1
  814. package/dist/tests/parameter-validation.test.js.map +0 -1
  815. package/dist/tests/project-detector.test.d.ts.map +0 -1
  816. package/dist/tests/project-detector.test.js.map +0 -1
  817. package/dist/tests/schema-migration.test.d.ts.map +0 -1
  818. package/dist/tests/schema-migration.test.js.map +0 -1
  819. package/dist/tests/sql-dump-converters.test.d.ts.map +0 -1
  820. package/dist/tests/sql-dump-converters.test.js.map +0 -1
  821. package/dist/tests/sql-dump-cross-database.test.d.ts.map +0 -1
  822. package/dist/tests/sql-dump-cross-database.test.js.map +0 -1
  823. package/dist/tests/sql-dump-default-conversions.test.d.ts.map +0 -1
  824. package/dist/tests/sql-dump-default-conversions.test.js.map +0 -1
  825. package/dist/tests/sql-dump-fk-constraints.test.d.ts.map +0 -1
  826. package/dist/tests/sql-dump-fk-constraints.test.js.map +0 -1
  827. package/dist/tests/sql-dump-indexes.test.d.ts.map +0 -1
  828. package/dist/tests/sql-dump-indexes.test.js.map +0 -1
  829. package/dist/tests/sql-dump-integration.test.d.ts.map +0 -1
  830. package/dist/tests/sql-dump-integration.test.js.map +0 -1
  831. package/dist/tests/sql-dump-table-ordering.test.d.ts +0 -8
  832. package/dist/tests/sql-dump-table-ordering.test.d.ts.map +0 -1
  833. package/dist/tests/sql-dump-table-ordering.test.js.map +0 -1
  834. package/dist/tests/tasks.auto-pruning-decision-link.test.d.ts.map +0 -1
  835. package/dist/tests/tasks.auto-pruning-decision-link.test.js.map +0 -1
  836. package/dist/tests/tasks.auto-pruning-partial.test.d.ts.map +0 -1
  837. package/dist/tests/tasks.auto-pruning-partial.test.js.map +0 -1
  838. package/dist/tests/tasks.auto-pruning-persistence.test.d.ts.map +0 -1
  839. package/dist/tests/tasks.auto-pruning-persistence.test.js.map +0 -1
  840. package/dist/tests/tasks.auto-pruning-safety.test.d.ts.map +0 -1
  841. package/dist/tests/tasks.auto-pruning-safety.test.js.map +0 -1
  842. package/dist/tests/tasks.dependencies.test.d.ts.map +0 -1
  843. package/dist/tests/tasks.dependencies.test.js.map +0 -1
  844. package/dist/tests/tasks.file-actions-integration.test.d.ts.map +0 -1
  845. package/dist/tests/tasks.file-actions-integration.test.js.map +0 -1
  846. package/dist/tests/tasks.file-actions-validation.test.d.ts.map +0 -1
  847. package/dist/tests/tasks.file-actions-validation.test.js.map +0 -1
  848. package/dist/tests/tasks.link-file-backward-compat.test.d.ts.map +0 -1
  849. package/dist/tests/tasks.link-file-backward-compat.test.js.map +0 -1
  850. package/dist/tests/tasks.watch-files-action.test.d.ts.map +0 -1
  851. package/dist/tests/tasks.watch-files-action.test.js.map +0 -1
  852. package/dist/tests/tasks.watch-files-parameter.test.d.ts.map +0 -1
  853. package/dist/tests/tasks.watch-files-parameter.test.js.map +0 -1
  854. package/dist/tests/two-step-git-completion.test.d.ts.map +0 -1
  855. package/dist/tests/two-step-git-completion.test.js.map +0 -1
  856. package/dist/tests/type-conversion.test.d.ts.map +0 -1
  857. package/dist/tests/type-conversion.test.js.map +0 -1
  858. package/dist/tests/vcs-staging.test.d.ts.map +0 -1
  859. package/dist/tests/vcs-staging.test.js.map +0 -1
  860. package/dist/utils/sql-dump.d.ts +0 -102
  861. package/dist/utils/sql-dump.d.ts.map +0 -1
  862. package/dist/utils/sql-dump.js +0 -1590
  863. package/dist/utils/sql-dump.js.map +0 -1
  864. /package/dist/tests/{connection-manager-integration.test.d.ts → database/connection/connection-manager-integration.test.d.ts} +0 -0
  865. /package/dist/tests/{connection-manager.test.d.ts → database/connection/connection-manager.test.d.ts} +0 -0
  866. /package/dist/tests/{multi-project.test.d.ts → database/multi-project/multi-project.test.d.ts} +0 -0
  867. /package/dist/tests/{type-conversion.test.d.ts → database/sql-dump/type-conversion.test.d.ts} +0 -0
  868. /package/dist/tests/{dump-import.test.d.ts → docker/dump-import.test.d.ts} +0 -0
  869. /package/dist/tests/{multi-project-migration.test.d.ts → docker/multi-project-migration.test.d.ts} +0 -0
  870. /package/dist/tests/{schema-migration.test.d.ts → docker/schema-migration.test.d.ts} +0 -0
  871. /package/dist/tests/{batch-validation-comprehensive.test.d.ts → feature/decision/batch-validation-comprehensive.test.d.ts} +0 -0
  872. /package/dist/tests/{batch-validation-integration.test.d.ts → feature/decision/batch-validation-integration.test.d.ts} +0 -0
  873. /package/dist/tests/{context-modular.test.d.ts → feature/decision/context-modular.test.d.ts} +0 -0
  874. /package/dist/tests/{help-system.test.d.ts → feature/help/help-system.test.d.ts} +0 -0
  875. /package/dist/tests/{git-aware-completion.test.d.ts → feature/vcs/git-aware-completion.test.d.ts} +0 -0
  876. /package/dist/tests/{two-step-git-completion.test.d.ts → feature/vcs/two-step-git-completion.test.d.ts} +0 -0
  877. /package/dist/tests/{vcs-staging.test.d.ts → feature/vcs/vcs-staging.test.d.ts} +0 -0
  878. /package/dist/tests/{config-loader.test.d.ts → unit/utils/config-loader.test.d.ts} +0 -0
  879. /package/dist/tests/{project-detector.test.d.ts → unit/utils/project-detector.test.d.ts} +0 -0
  880. /package/dist/tests/{batch-validation.test.d.ts → unit/validation/batch-validation.test.d.ts} +0 -0
  881. /package/dist/tests/{parameter-validation.test.d.ts → unit/validation/parameter-validation.test.d.ts} +0 -0
@@ -1,1590 +0,0 @@
1
- // sql-dump.ts - Utility functions for generating SQL dump files
2
- import knex from 'knex';
3
- import { SchemaInspector } from 'knex-schema-inspector';
4
- import { convertIdentifierQuotes, convertTimestampFunctions, } from './sql-dump-converters.js';
5
- import { debugLog } from './debug-logger.js';
6
- /**
7
- * Convert data type from source format to target format using metadata
8
- */
9
- function convertDataType(columnType, targetFormat, maxLength) {
10
- const upperType = columnType.toUpperCase();
11
- if (targetFormat === 'mysql') {
12
- // MySQL-specific conversions
13
- if (upperType.includes('SERIAL') || upperType.includes('BIGSERIAL')) {
14
- return 'BIGINT AUTO_INCREMENT';
15
- }
16
- if (upperType.includes('TEXT')) {
17
- return 'TEXT';
18
- }
19
- if (upperType.includes('VARCHAR')) {
20
- // Use maxLength from metadata
21
- const length = maxLength && maxLength <= 191 ? maxLength : 191;
22
- return `VARCHAR(${length})`;
23
- }
24
- if (upperType.includes('TIMESTAMP') || upperType.includes('TIMESTAMPTZ')) {
25
- return 'DATETIME';
26
- }
27
- if (upperType.includes('BOOLEAN') || upperType === 'BOOL') {
28
- return 'TINYINT(1)';
29
- }
30
- if (upperType === 'INTEGER' || upperType === 'INT') {
31
- return 'INT';
32
- }
33
- if (upperType.includes('BIGINT')) {
34
- return 'BIGINT';
35
- }
36
- }
37
- else if (targetFormat === 'postgresql') {
38
- // PostgreSQL-specific conversions
39
- if (upperType.includes('AUTOINCREMENT') || upperType.includes('AUTO_INCREMENT')) {
40
- return 'SERIAL';
41
- }
42
- if (upperType.includes('DATETIME')) {
43
- return 'TIMESTAMP';
44
- }
45
- if (upperType.includes('TINYINT') || upperType === 'BIT') {
46
- return 'BOOLEAN';
47
- }
48
- if (upperType.includes('TEXT')) {
49
- return 'TEXT';
50
- }
51
- if (upperType.includes('VARCHAR')) {
52
- const length = maxLength || 255;
53
- return `VARCHAR(${length})`;
54
- }
55
- }
56
- else if (targetFormat === 'sqlite') {
57
- // SQLite-specific conversions
58
- if (upperType.includes('SERIAL') || upperType.includes('AUTO_INCREMENT') || upperType.includes('AUTOINCREMENT')) {
59
- return 'INTEGER';
60
- }
61
- if (upperType.includes('VARCHAR') || upperType.includes('TEXT')) {
62
- return 'TEXT';
63
- }
64
- if (upperType.includes('TINYINT') || upperType.includes('BOOLEAN')) {
65
- return 'INTEGER';
66
- }
67
- if (upperType.includes('DATETIME') || upperType.includes('TIMESTAMP')) {
68
- return 'INTEGER'; // SQLite stores as Unix timestamp
69
- }
70
- }
71
- // Default: return as-is
72
- return columnType;
73
- }
74
- /**
75
- * Convert default value from SQLite functions to target format
76
- * Handles: unixepoch() → UNIX_TIMESTAMP() / EXTRACT(epoch FROM NOW())
77
- * strftime() → DATE_FORMAT() / TO_CHAR()
78
- */
79
- function convertDefaultValue(defaultValue, targetFormat) {
80
- if (!defaultValue) {
81
- return null;
82
- }
83
- const lower = defaultValue.toLowerCase().trim();
84
- // SQLite unixepoch() conversions
85
- if (lower.includes('unixepoch()') || lower === 'unixepoch()') {
86
- if (targetFormat === 'mysql') {
87
- // MySQL 8.0+: Use CAST to explicitly convert UNIX_TIMESTAMP() to SIGNED INTEGER
88
- // Wrapped in parentheses for expression syntax
89
- return '(CAST(UNIX_TIMESTAMP() AS SIGNED))';
90
- }
91
- else if (targetFormat === 'postgresql') {
92
- return 'EXTRACT(epoch FROM NOW())::INTEGER';
93
- }
94
- return null; // Remove for SQLite
95
- }
96
- // SQLite strftime('%s', 'now') - Unix timestamp (INTEGER)
97
- // Must check BEFORE generic strftime to handle this specific case
98
- if (lower.includes("strftime('%s'") || lower.includes('strftime("%s"')) {
99
- if (targetFormat === 'mysql') {
100
- // MySQL 8.0+: Use CAST to explicitly convert UNIX_TIMESTAMP() to SIGNED INTEGER
101
- // Wrapped in parentheses for expression syntax
102
- return '(CAST(UNIX_TIMESTAMP() AS SIGNED))';
103
- }
104
- else if (targetFormat === 'postgresql') {
105
- return 'EXTRACT(epoch FROM NOW())::INTEGER';
106
- }
107
- return null;
108
- }
109
- // MySQL UNIX_TIMESTAMP() - already MySQL syntax, needs CAST wrapping
110
- // Match both "unix_timestamp()" and "UNIX_TIMESTAMP()" case-insensitively
111
- if (lower.includes('unix_timestamp')) {
112
- if (targetFormat === 'mysql') {
113
- // MySQL 8.0+: Wrap UNIX_TIMESTAMP() with CAST for type safety
114
- return '(CAST(UNIX_TIMESTAMP() AS SIGNED))';
115
- }
116
- else if (targetFormat === 'postgresql') {
117
- return 'EXTRACT(epoch FROM NOW())::INTEGER';
118
- }
119
- else if (targetFormat === 'sqlite') {
120
- return 'unixepoch()';
121
- }
122
- return null;
123
- }
124
- // SQLite strftime conversions (datetime formats)
125
- if (lower.includes('strftime')) {
126
- if (targetFormat === 'mysql') {
127
- // strftime('%Y-%m-%d %H:%M:%S', 'now') → NOW()
128
- return 'NOW()';
129
- }
130
- else if (targetFormat === 'postgresql') {
131
- return 'NOW()';
132
- }
133
- return null;
134
- }
135
- // Remove parentheses for simple values
136
- let cleanValue = defaultValue;
137
- if (lower.startsWith('(') && lower.endsWith(')')) {
138
- cleanValue = defaultValue.substring(1, defaultValue.length - 1);
139
- }
140
- // For numeric defaults, normalize floating point values
141
- // Remove trailing .0 (e.g., 1.0 → 1) to avoid type mismatches
142
- const trimmed = cleanValue.trim();
143
- if (/^\d+\.0+$/.test(trimmed)) {
144
- return trimmed.replace(/\.0+$/, '');
145
- }
146
- // Quote string literals if not already quoted and not a number
147
- if (!/^['"]/.test(trimmed) && !/^-?\d+(\.\d+)?$/.test(trimmed) && !/^(true|false|null|current_timestamp|now\(\)|unix_timestamp\(\))$/i.test(trimmed)) {
148
- return `'${trimmed}'`;
149
- }
150
- return trimmed;
151
- }
152
- /**
153
- * Quote identifier (table or column name) for target database
154
- */
155
- export function quoteIdentifier(name, format) {
156
- switch (format) {
157
- case 'mysql':
158
- return `\`${name}\``;
159
- case 'postgresql':
160
- case 'sqlite':
161
- return `"${name}"`;
162
- default:
163
- return `"${name}"`;
164
- }
165
- }
166
- /**
167
- * Build column definition from Column metadata
168
- */
169
- function buildColumnDefinition(col, targetFormat) {
170
- const quotedName = quoteIdentifier(col.name, targetFormat);
171
- let dataType = convertDataType(col.data_type, targetFormat, col.max_length);
172
- // MySQL: TEXT columns cannot be used in UNIQUE/PRIMARY KEY constraints without prefix length
173
- // Convert TEXT to VARCHAR(191) for utf8mb4 compatibility (768 bytes ÷ 4 bytes/char = 191)
174
- if (targetFormat === 'mysql' && dataType.toUpperCase() === 'TEXT') {
175
- if (col.is_unique || col.is_primary_key || col.foreign_key_table || col.in_composite_unique) {
176
- dataType = 'VARCHAR(191)';
177
- }
178
- }
179
- let def = `${quotedName} ${dataType}`;
180
- // Handle NOT NULL constraint
181
- if (col.is_nullable === false) {
182
- def += ' NOT NULL';
183
- }
184
- // Handle DEFAULT value
185
- if (col.default_value !== null && col.default_value !== undefined) {
186
- let convertedDefault = convertDefaultValue(String(col.default_value), targetFormat);
187
- if (convertedDefault !== null && convertedDefault !== '') {
188
- // MySQL restrictions for DEFAULT values
189
- const isTextColumn = dataType.toUpperCase().includes('TEXT') || dataType.toUpperCase().includes('BLOB');
190
- const isFunctionCall = convertedDefault.includes('(') && convertedDefault.includes(')');
191
- const isIntegerColumn = dataType.toUpperCase().includes('INT');
192
- const isBooleanColumn = dataType.toUpperCase().includes('BOOLEAN');
193
- // PostgreSQL: Convert integer defaults to boolean for BOOLEAN columns
194
- if (targetFormat === 'postgresql' && isBooleanColumn && /^[01]$/.test(convertedDefault)) {
195
- convertedDefault = convertedDefault === '1' ? 'TRUE' : 'FALSE';
196
- }
197
- if (targetFormat === 'mysql') {
198
- // MySQL doesn't allow DEFAULT on TEXT/BLOB columns
199
- if (isTextColumn) {
200
- // Skip DEFAULT - application must handle at runtime
201
- }
202
- // MySQL DOES support certain function calls as DEFAULT for INTEGER columns
203
- // (e.g., UNIX_TIMESTAMP(), CURRENT_TIMESTAMP)
204
- // Only skip if conversion returned null (meaning function not supported)
205
- else {
206
- def += ` DEFAULT ${convertedDefault}`;
207
- }
208
- }
209
- else {
210
- def += ` DEFAULT ${convertedDefault}`;
211
- }
212
- }
213
- }
214
- // Handle AUTO_INCREMENT for MySQL
215
- if (targetFormat === 'mysql' && col.is_generated && col.generation_expression === null) {
216
- if (!def.includes('AUTO_INCREMENT')) {
217
- def += ' AUTO_INCREMENT';
218
- }
219
- }
220
- // Handle UNIQUE constraint (skip if already PRIMARY KEY)
221
- if (col.is_unique && !col.is_primary_key) {
222
- def += ' UNIQUE';
223
- }
224
- return def;
225
- }
226
- /**
227
- * Build FOREIGN KEY definition from ForeignKey metadata
228
- */
229
- function buildForeignKeyDefinition(fk, targetFormat) {
230
- const quotedColumn = quoteIdentifier(fk.column, targetFormat);
231
- const quotedForeignTable = quoteIdentifier(fk.foreign_key_table, targetFormat);
232
- const quotedForeignColumn = quoteIdentifier(fk.foreign_key_column, targetFormat);
233
- let fkDef = `FOREIGN KEY (${quotedColumn}) REFERENCES ${quotedForeignTable}(${quotedForeignColumn})`;
234
- // Add ON DELETE clause
235
- if (fk.on_delete && fk.on_delete !== 'NO ACTION') {
236
- fkDef += ` ON DELETE ${fk.on_delete}`;
237
- }
238
- // Add ON UPDATE clause
239
- if (fk.on_update && fk.on_update !== 'NO ACTION') {
240
- fkDef += ` ON UPDATE ${fk.on_update}`;
241
- }
242
- return fkDef;
243
- }
244
- /**
245
- * Enforce NOT NULL constraints on PRIMARY KEY columns
246
- * MySQL and PostgreSQL require all PRIMARY KEY columns to be NOT NULL
247
- */
248
- function enforceNotNullOnPrimaryKey(createSql, pkColumns) {
249
- if (pkColumns.length === 0) {
250
- return createSql;
251
- }
252
- // Split the CREATE TABLE statement to process column definitions
253
- const lines = createSql.split('\n');
254
- const processedLines = lines.map((line) => {
255
- // Check if this line defines one of the PRIMARY KEY columns
256
- for (const pkCol of pkColumns) {
257
- // Match column definition (handle different quote styles)
258
- const colPattern = new RegExp(`^\\s*[\`"']?${pkCol}[\`"']?\\s+`, 'i');
259
- if (colPattern.test(line)) {
260
- // Check if NOT NULL is already present
261
- if (!/NOT\s+NULL/i.test(line)) {
262
- // Find position to insert NOT NULL (before DEFAULT, FOREIGN KEY, CHECK, or comma/closing paren)
263
- const insertBeforePatterns = [
264
- /\s+DEFAULT/i,
265
- /\s+FOREIGN\s+KEY/i,
266
- /\s+CHECK/i,
267
- /,\s*$/,
268
- /\)\s*$/,
269
- ];
270
- let insertPos = line.length;
271
- for (const pattern of insertBeforePatterns) {
272
- const match = line.match(pattern);
273
- if (match && match.index !== undefined) {
274
- insertPos = Math.min(insertPos, match.index);
275
- }
276
- }
277
- // Insert NOT NULL
278
- return line.slice(0, insertPos) + ' NOT NULL' + line.slice(insertPos);
279
- }
280
- }
281
- }
282
- return line;
283
- });
284
- return processedLines.join('\n');
285
- }
286
- /**
287
- * Get primary key columns for a table
288
- */
289
- export async function getPrimaryKeyColumns(knex, table) {
290
- const client = knex.client.config.client;
291
- if (client === 'better-sqlite3' || client === 'sqlite3') {
292
- // SQLite: Use PRAGMA table_info
293
- const result = await knex.raw(`PRAGMA table_info(${table})`);
294
- return result
295
- .filter((col) => col.pk > 0)
296
- .sort((a, b) => a.pk - b.pk)
297
- .map((col) => col.name);
298
- }
299
- else if (client === 'mysql' || client === 'mysql2') {
300
- // MySQL: Query information_schema
301
- const result = await knex.raw(`
302
- SELECT COLUMN_NAME
303
- FROM information_schema.KEY_COLUMN_USAGE
304
- WHERE TABLE_SCHEMA = DATABASE()
305
- AND TABLE_NAME = ?
306
- AND CONSTRAINT_NAME = 'PRIMARY'
307
- ORDER BY ORDINAL_POSITION
308
- `, [table]);
309
- return result[0].map((row) => row.COLUMN_NAME);
310
- }
311
- else if (client === 'pg') {
312
- // PostgreSQL: Query information_schema
313
- const result = await knex.raw(`
314
- SELECT a.attname AS column_name
315
- FROM pg_index i
316
- JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
317
- WHERE i.indrelid = ?::regclass
318
- AND i.indisprimary
319
- ORDER BY a.attnum
320
- `, [table]);
321
- return result.rows.map((row) => row.column_name);
322
- }
323
- throw new Error(`Unsupported database client: ${client}`);
324
- }
325
- /**
326
- * Get CREATE TABLE statement for a table using knex-schema-inspector
327
- * Replaces regex-based SQL conversion with metadata-driven approach
328
- */
329
- export async function getCreateTableStatement(knex, table, targetFormat) {
330
- const client = knex.client.config.client;
331
- // Initialize schema inspector (database-agnostic)
332
- const inspector = SchemaInspector(knex);
333
- // Get column metadata
334
- const columns = await inspector.columnInfo(table);
335
- if (columns.length === 0) {
336
- throw new Error(`Table ${table} not found or has no columns`);
337
- }
338
- // Fix: knex-schema-inspector doesn't detect composite PRIMARY KEYs and UNIQUE constraints from SQLite properly
339
- // Manually detect them using PRAGMA index_list
340
- const compositeUniqueConstraints = []; // Track composite UNIQUE constraints
341
- let compositePrimaryKey = null; // Track composite PRIMARY KEY
342
- if (client === 'better-sqlite3' || client === 'sqlite3') {
343
- const indexResult = await knex.raw(`PRAGMA index_list(${table})`);
344
- // Knex raw() returns an array directly for SQLite
345
- const indexes = Array.isArray(indexResult) ? indexResult : [];
346
- for (const index of indexes) {
347
- // Check for PRIMARY KEY index
348
- if (index.origin === 'pk' && index.unique === 1) {
349
- const indexInfoResult = await knex.raw(`PRAGMA index_info(${index.name})`);
350
- const indexInfo = Array.isArray(indexInfoResult) ? indexInfoResult : [];
351
- const columnNames = indexInfo.map((idxCol) => idxCol.name);
352
- if (columnNames.length > 1) {
353
- // Composite PRIMARY KEY detected
354
- compositePrimaryKey = columnNames;
355
- debugLog('DEBUG', `Found composite PRIMARY KEY on ${table}(${columnNames.join(', ')}) from ${index.name}`);
356
- }
357
- }
358
- // Check if this is a UNIQUE index (skip PRIMARY KEY indexes)
359
- else if (index.unique === 1 && index.origin !== 'pk') {
360
- // Get columns in this index
361
- const indexInfoResult = await knex.raw(`PRAGMA index_info(${index.name})`);
362
- const indexInfo = Array.isArray(indexInfoResult) ? indexInfoResult : [];
363
- const columnNames = indexInfo.map((idxCol) => idxCol.name);
364
- if (columnNames.length === 1) {
365
- // Single-column UNIQUE - mark column as unique
366
- const col = columns.find(c => c.name === columnNames[0]);
367
- if (col && !col.is_primary_key) {
368
- col.is_unique = true;
369
- debugLog('DEBUG', `Marked ${table}.${col.name} as UNIQUE (single-column from ${index.name})`);
370
- }
371
- }
372
- else if (columnNames.length > 1) {
373
- // Composite UNIQUE - add to table-level constraints
374
- compositeUniqueConstraints.push(columnNames);
375
- debugLog('DEBUG', `Found composite UNIQUE on ${table}(${columnNames.join(', ')}) from ${index.name}`);
376
- // For MySQL: Convert TEXT to VARCHAR(191) for columns in composite UNIQUE
377
- if (targetFormat === 'mysql') {
378
- for (const colName of columnNames) {
379
- const col = columns.find(c => c.name === colName);
380
- if (col && !col.is_primary_key) {
381
- // Mark as part of composite unique (will be converted to VARCHAR later)
382
- col.in_composite_unique = true;
383
- }
384
- }
385
- }
386
- }
387
- }
388
- }
389
- }
390
- // Build column definitions using buildColumnDefinition()
391
- const columnDefs = columns.map(col => buildColumnDefinition(col, targetFormat));
392
- // Add PRIMARY KEY constraint (with MySQL prefix length handling)
393
- // Use composite PRIMARY KEY if detected, otherwise fall back to column metadata
394
- const pkColumns = compositePrimaryKey || columns.filter(col => col.is_primary_key).map(col => col.name);
395
- if (pkColumns.length > 0) {
396
- // For MySQL: Apply (191) prefix to TEXT/long VARCHAR columns
397
- if (targetFormat === 'mysql') {
398
- const processedPkCols = pkColumns.map((colName) => {
399
- const col = columns.find(c => c.name === colName);
400
- if (col && (col.data_type.toUpperCase() === 'TEXT' ||
401
- (col.data_type.toUpperCase().includes('VARCHAR') && col.max_length && col.max_length > 191))) {
402
- return `${quoteIdentifier(colName, targetFormat)}(191)`;
403
- }
404
- return quoteIdentifier(colName, targetFormat);
405
- }).join(', ');
406
- columnDefs.push(`PRIMARY KEY (${processedPkCols})`);
407
- }
408
- else {
409
- const quotedPkColumns = pkColumns.map(col => quoteIdentifier(col, targetFormat));
410
- columnDefs.push(`PRIMARY KEY (${quotedPkColumns.join(', ')})`);
411
- }
412
- }
413
- // Add FOREIGN KEY constraints using buildForeignKeyDefinition()
414
- const foreignKeys = await inspector.foreignKeys(table);
415
- for (const fk of foreignKeys) {
416
- columnDefs.push(buildForeignKeyDefinition(fk, targetFormat));
417
- }
418
- // Add composite UNIQUE constraints (from SQLite multi-column UNIQUE indexes)
419
- for (const uniqueCols of compositeUniqueConstraints) {
420
- const quotedCols = uniqueCols.map(col => quoteIdentifier(col, targetFormat)).join(', ');
421
- columnDefs.push(`UNIQUE (${quotedCols})`);
422
- }
423
- // Build CREATE TABLE statement with IF NOT EXISTS for idempotency
424
- const quotedTable = quoteIdentifier(table, targetFormat);
425
- const createSql = `CREATE TABLE IF NOT EXISTS ${quotedTable} (\n ${columnDefs.join(',\n ')}\n)`;
426
- // Add database-specific table options
427
- if (targetFormat === 'mysql') {
428
- return createSql + ' ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;';
429
- }
430
- return createSql + ';';
431
- }
432
- /**
433
- * Get all table names from the database (excluding system tables)
434
- */
435
- export async function getAllTables(knex, includeKnexTables = false) {
436
- const client = knex.client.config.client;
437
- if (client === 'better-sqlite3' || client === 'sqlite3') {
438
- const knexFilter = includeKnexTables ? '' : "AND name NOT LIKE 'knex_%'";
439
- const result = await knex.raw(`
440
- SELECT name FROM sqlite_master
441
- WHERE type='table'
442
- AND name NOT LIKE 'sqlite_%'
443
- ${knexFilter}
444
- ORDER BY name
445
- `);
446
- return result.map((row) => row.name);
447
- }
448
- else if (client === 'mysql' || client === 'mysql2') {
449
- const result = await knex.raw('SHOW TABLES');
450
- const tableKey = Object.keys(result[0][0])[0];
451
- const tables = result[0].map((row) => row[tableKey]);
452
- return includeKnexTables ? tables : tables.filter((t) => !t.startsWith('knex_'));
453
- }
454
- else if (client === 'pg') {
455
- const knexFilter = includeKnexTables ? '' : "AND tablename NOT LIKE 'knex_%'";
456
- const result = await knex.raw(`
457
- SELECT tablename FROM pg_tables
458
- WHERE schemaname = 'public'
459
- ${knexFilter}
460
- ORDER BY tablename
461
- `);
462
- return result.rows.map((row) => row.tablename);
463
- }
464
- throw new Error(`Unsupported database client: ${client}`);
465
- }
466
- /**
467
- * Get all view names from the database
468
- */
469
- export async function getAllViews(knex) {
470
- const client = knex.client.config.client;
471
- if (client === 'better-sqlite3' || client === 'sqlite3') {
472
- const result = await knex.raw(`
473
- SELECT name FROM sqlite_master
474
- WHERE type='view'
475
- ORDER BY name
476
- `);
477
- return result.map((row) => row.name);
478
- }
479
- else if (client === 'mysql' || client === 'mysql2') {
480
- const result = await knex.raw(`
481
- SELECT TABLE_NAME as name
482
- FROM information_schema.VIEWS
483
- WHERE TABLE_SCHEMA = DATABASE()
484
- ORDER BY TABLE_NAME
485
- `);
486
- return result[0].map((row) => row.name);
487
- }
488
- else if (client === 'pg') {
489
- const result = await knex.raw(`
490
- SELECT viewname as name
491
- FROM pg_views
492
- WHERE schemaname = 'public'
493
- ORDER BY viewname
494
- `);
495
- return result.rows.map((row) => row.name);
496
- }
497
- throw new Error(`Unsupported database client: ${client}`);
498
- }
499
- /**
500
- * Get all indexes for a table
501
- */
502
- export async function getAllIndexes(knex, table) {
503
- const client = knex.client.config.client;
504
- if (client === 'better-sqlite3' || client === 'sqlite3') {
505
- const result = await knex.raw(`
506
- SELECT name FROM sqlite_master
507
- WHERE type='index'
508
- AND tbl_name=?
509
- AND sql IS NOT NULL
510
- ORDER BY name
511
- `, [table]);
512
- return result.map((row) => row.name);
513
- }
514
- else if (client === 'mysql' || client === 'mysql2') {
515
- const result = await knex.raw(`
516
- SHOW INDEXES FROM ?? WHERE Key_name != 'PRIMARY'
517
- `, [table]);
518
- // Group by index name (indexes can span multiple columns)
519
- const indexNames = new Set();
520
- for (const row of result[0]) {
521
- indexNames.add(row.Key_name);
522
- }
523
- return Array.from(indexNames).sort();
524
- }
525
- else if (client === 'pg') {
526
- const result = await knex.raw(`
527
- SELECT indexname
528
- FROM pg_indexes
529
- WHERE schemaname = 'public'
530
- AND tablename = ?
531
- AND indexname NOT LIKE '%_pkey'
532
- ORDER BY indexname
533
- `, [table]);
534
- return result.rows.map((row) => row.indexname);
535
- }
536
- // For other database clients
537
- return [];
538
- }
539
- /**
540
- * Get CREATE INDEX statement for an index
541
- */
542
- export async function getCreateIndexStatement(knex, indexName, targetFormat) {
543
- const client = knex.client.config.client;
544
- if (client === 'better-sqlite3' || client === 'sqlite3') {
545
- const result = await knex.raw(`
546
- SELECT sql, tbl_name FROM sqlite_master
547
- WHERE type='index' AND name=?
548
- `, [indexName]);
549
- if (result.length === 0 || !result[0].sql) {
550
- throw new Error(`Index ${indexName} not found`);
551
- }
552
- let createSql = result[0].sql;
553
- const tableName = result[0].tbl_name;
554
- // Convert to target format if needed
555
- if (targetFormat === 'mysql') {
556
- createSql = convertIdentifierQuotes(createSql, 'mysql');
557
- // MySQL has a 3072 byte limit for index keys (with utf8mb4, that's ~768 chars)
558
- // Add prefix length (191 chars) to VARCHAR columns longer than 191 to stay under limit
559
- // Match: CREATE [UNIQUE] INDEX name ON table (col1, col2, ...)
560
- const match = createSql.match(/\((.*?)\)(?:\s|$)/);
561
- if (match) {
562
- const columns = match[1];
563
- // Get column info for the table
564
- const columnInfo = await knex(tableName).columnInfo();
565
- // Process each column in the index
566
- const processedColumns = columns.split(',').map((col) => {
567
- // Remove quotes/backticks and DESC/ASC keywords
568
- let colSpec = col.trim().replace(/[`"]/g, '');
569
- const colName = colSpec.replace(/\s+(DESC|ASC)$/i, '').trim();
570
- const info = columnInfo[colName];
571
- // If VARCHAR/TEXT longer than 191 chars, add prefix length
572
- if (info && info.type) {
573
- const type = info.type.toLowerCase();
574
- if (type.includes('varchar') || type.includes('text')) {
575
- // Check maxLength property first (SQLite returns this separately)
576
- const maxLength = info.maxLength;
577
- if (maxLength && parseInt(maxLength) > 191) {
578
- return `\`${colName}\`(191)`;
579
- }
580
- // Also try extracting length from VARCHAR(n) in type string
581
- const lengthMatch = type.match(/varchar\((\d+)\)/);
582
- if (lengthMatch && parseInt(lengthMatch[1]) > 191) {
583
- return `\`${colName}\`(191)`;
584
- }
585
- else if (type.includes('text')) {
586
- // TEXT columns have no fixed length, always add prefix
587
- return `\`${colName}\`(191)`;
588
- }
589
- }
590
- }
591
- return `\`${colName}\``;
592
- }).join(', ');
593
- createSql = createSql.replace(/\((.*?)\)(?:\s|$)/, `(${processedColumns})`);
594
- }
595
- }
596
- else if (targetFormat === 'postgresql') {
597
- createSql = convertIdentifierQuotes(createSql, 'postgresql');
598
- }
599
- return createSql + ';';
600
- }
601
- else if (client === 'mysql' || client === 'mysql2') {
602
- // For MySQL, we need to find which table the index belongs to
603
- // First, get all tables and search for the index
604
- const tablesResult = await knex.raw('SHOW TABLES');
605
- const tableKey = Object.keys(tablesResult[0][0])[0];
606
- const tables = tablesResult[0].map((row) => row[tableKey]);
607
- let indexInfo = null;
608
- let tableName = '';
609
- // Search for the index in all tables
610
- for (const table of tables) {
611
- const result = await knex.raw(`SHOW INDEXES FROM ?? WHERE Key_name = ?`, [table, indexName]);
612
- if (result[0].length > 0) {
613
- indexInfo = result[0];
614
- tableName = table;
615
- break;
616
- }
617
- }
618
- if (!indexInfo || indexInfo.length === 0) {
619
- throw new Error(`Index ${indexName} not found`);
620
- }
621
- const isUnique = indexInfo[0].Non_unique === 0;
622
- // Get column info for prefix length handling
623
- const columnInfo = await knex(tableName).columnInfo();
624
- // Build column list with proper prefix lengths
625
- const columns = indexInfo.map((row) => {
626
- const colName = row.Column_name;
627
- const colMeta = columnInfo[colName];
628
- // Handle prefix length for long VARCHAR/TEXT columns
629
- if (colMeta && colMeta.type) {
630
- const type = colMeta.type.toLowerCase();
631
- if (type.includes('varchar') || type.includes('text')) {
632
- const maxLength = colMeta.maxLength;
633
- // Extract length from type string like "varchar(255)"
634
- const lengthMatch = type.match(/varchar\((\d+)\)/);
635
- const typeLength = lengthMatch ? parseInt(lengthMatch[1]) : null;
636
- if ((maxLength && parseInt(maxLength) > 191) || (typeLength && typeLength > 191) || type.includes('text')) {
637
- return `\`${colName}\`(191)`;
638
- }
639
- }
640
- }
641
- return `\`${colName}\``;
642
- }).join(', ');
643
- const uniqueStr = isUnique ? 'UNIQUE ' : '';
644
- let createSql = `CREATE ${uniqueStr}INDEX \`${indexName}\` ON \`${tableName}\` (${columns})`;
645
- // Apply cross-database conversion
646
- if (targetFormat === 'postgresql') {
647
- createSql = convertIdentifierQuotes(createSql, 'postgresql');
648
- }
649
- else if (targetFormat === 'sqlite') {
650
- createSql = convertIdentifierQuotes(createSql, 'sqlite');
651
- // Remove prefix lengths for SQLite (not supported)
652
- createSql = createSql.replace(/\(191\)/g, '');
653
- }
654
- return createSql + ';';
655
- }
656
- else if (client === 'pg') {
657
- // Get index definition from PostgreSQL
658
- const result = await knex.raw(`
659
- SELECT indexdef
660
- FROM pg_indexes
661
- WHERE schemaname = 'public' AND indexname = ?
662
- `, [indexName]);
663
- if (result.rows.length === 0) {
664
- throw new Error(`Index ${indexName} not found`);
665
- }
666
- let createSql = result.rows[0].indexdef;
667
- // Apply cross-database conversion
668
- if (targetFormat === 'mysql') {
669
- createSql = convertIdentifierQuotes(createSql, 'mysql');
670
- // Handle prefix length for MySQL
671
- // Extract table name from the CREATE INDEX statement
672
- const tableMatch = createSql.match(/ON\s+(["`]?\w+["`]?)/i);
673
- if (tableMatch) {
674
- const tableName = tableMatch[1].replace(/["`]/g, '');
675
- const columnInfo = await knex(tableName).columnInfo();
676
- // Find column list in the index definition
677
- const colMatch = createSql.match(/\((.*?)\)(?:\s|$)/);
678
- if (colMatch) {
679
- const columns = colMatch[1];
680
- const processedColumns = columns.split(',').map((col) => {
681
- const colName = col.trim().replace(/["`]/g, '').replace(/\s+(DESC|ASC)$/i, '').trim();
682
- const info = columnInfo[colName];
683
- if (info && info.type) {
684
- const type = info.type.toLowerCase();
685
- if (type.includes('varchar') || type.includes('text')) {
686
- const maxLength = info.maxLength;
687
- const lengthMatch = type.match(/varchar\((\d+)\)/);
688
- const typeLength = lengthMatch ? parseInt(lengthMatch[1]) : null;
689
- if ((maxLength && parseInt(maxLength) > 191) || (typeLength && typeLength > 191) || type.includes('text')) {
690
- return `\`${colName}\`(191)`;
691
- }
692
- }
693
- }
694
- return `\`${colName}\``;
695
- }).join(', ');
696
- createSql = createSql.replace(/\((.*?)\)(?:\s|$)/, `(${processedColumns})`);
697
- }
698
- }
699
- }
700
- else if (targetFormat === 'sqlite') {
701
- createSql = convertIdentifierQuotes(createSql, 'sqlite');
702
- }
703
- return createSql + ';';
704
- }
705
- throw new Error(`Unsupported database client: ${client}`);
706
- }
707
- /**
708
- * Get CREATE VIEW statement for a view
709
- */
710
- export async function getCreateViewStatement(knex, viewName, targetFormat) {
711
- const client = knex.client.config.client;
712
- if (client === 'better-sqlite3' || client === 'sqlite3') {
713
- // SQLite: Get from sqlite_master
714
- const result = await knex.raw(`
715
- SELECT sql FROM sqlite_master
716
- WHERE type='view' AND name=?
717
- `, [viewName]);
718
- if (result.length === 0 || !result[0].sql) {
719
- throw new Error(`View ${viewName} not found`);
720
- }
721
- let createSql = result[0].sql;
722
- // Convert SQLite syntax to target format if needed
723
- if (targetFormat === 'mysql') {
724
- // Convert to MySQL syntax using shared converters
725
- createSql = convertIdentifierQuotes(createSql, 'mysql');
726
- createSql = convertTimestampFunctions(createSql, 'mysql');
727
- }
728
- else if (targetFormat === 'postgresql') {
729
- // Convert to PostgreSQL syntax using shared converters
730
- createSql = convertIdentifierQuotes(createSql, 'postgresql');
731
- createSql = convertTimestampFunctions(createSql, 'postgresql');
732
- // Convert GROUP_CONCAT(col, sep) → string_agg(col, sep)
733
- createSql = createSql.replace(/GROUP_CONCAT\s*\(/gi, 'string_agg(');
734
- // Cast integer comparisons to be type-safe: column = 1 → column::integer = 1
735
- // This works for both boolean columns (TRUE::integer = 1) and integer enum columns
736
- createSql = createSql.replace(/(\w+)\s*=\s*([01])\b/g, '$1::integer = $2');
737
- }
738
- return createSql + ';';
739
- }
740
- else if (client === 'mysql' || client === 'mysql2') {
741
- // MySQL: Use SHOW CREATE VIEW
742
- const result = await knex.raw(`SHOW CREATE VIEW ??`, [viewName]);
743
- let createSql = result[0][0]['Create View'];
744
- if (targetFormat === 'sqlite') {
745
- // Convert MySQL to SQLite using shared converters
746
- createSql = convertIdentifierQuotes(createSql, 'sqlite');
747
- createSql = convertTimestampFunctions(createSql, 'sqlite');
748
- return createSql + ';';
749
- }
750
- else if (targetFormat === 'postgresql') {
751
- // Convert MySQL to PostgreSQL using shared converters
752
- createSql = convertIdentifierQuotes(createSql, 'postgresql');
753
- createSql = convertTimestampFunctions(createSql, 'postgresql');
754
- return createSql + ';';
755
- }
756
- return createSql + ';';
757
- }
758
- else if (client === 'pg') {
759
- // PostgreSQL: Get from pg_views
760
- const result = await knex.raw(`
761
- SELECT definition
762
- FROM pg_views
763
- WHERE schemaname = 'public' AND viewname = ?
764
- `, [viewName]);
765
- if (result.rows.length === 0) {
766
- throw new Error(`View ${viewName} not found`);
767
- }
768
- let createSql = `CREATE VIEW "${viewName}" AS ${result.rows[0].definition}`;
769
- if (targetFormat === 'mysql') {
770
- createSql = convertIdentifierQuotes(createSql, 'mysql');
771
- return createSql + ';';
772
- }
773
- else if (targetFormat === 'sqlite') {
774
- createSql = convertTimestampFunctions(createSql, 'sqlite');
775
- return createSql + ';';
776
- }
777
- return createSql + ';';
778
- }
779
- throw new Error(`Unsupported database client: ${client}`);
780
- }
781
- /**
782
- * Convert backtick-quoted identifiers to double-quoted identifiers
783
- * Only replaces backticks that are identifier quotes, not those inside string literals
784
- */
785
- function convertBackticksToDoubleQuotes(sql) {
786
- // Match backtick-quoted identifiers: `identifier`
787
- // Only matches word characters, dots, hyphens, and underscores (valid identifier chars)
788
- return sql.replace(/`([a-zA-Z0-9_\.\-]+)`/g, '"$1"');
789
- }
790
- /**
791
- * Format a value for SQL insertion
792
- */
793
- export function formatValue(value, format, table, column, columnType) {
794
- // Handle NULL
795
- if (value === null || value === undefined) {
796
- return 'NULL';
797
- }
798
- // Special case: knex_migrations.migration_time
799
- // Convert Unix timestamp (milliseconds) to datetime/timestamp string
800
- if (table === 'knex_migrations' && column === 'migration_time' && typeof value === 'number') {
801
- if (format === 'mysql') {
802
- const date = new Date(value);
803
- const year = date.getFullYear();
804
- const month = String(date.getMonth() + 1).padStart(2, '0');
805
- const day = String(date.getDate()).padStart(2, '0');
806
- const hours = String(date.getHours()).padStart(2, '0');
807
- const minutes = String(date.getMinutes()).padStart(2, '0');
808
- const seconds = String(date.getSeconds()).padStart(2, '0');
809
- return `'${year}-${month}-${day} ${hours}:${minutes}:${seconds}'`;
810
- }
811
- else if (format === 'postgresql') {
812
- // PostgreSQL: Use to_timestamp() function
813
- return `to_timestamp(${value / 1000})`; // Convert milliseconds to seconds
814
- }
815
- }
816
- // Handle numbers
817
- if (typeof value === 'number') {
818
- // Special case: PostgreSQL boolean columns stored as 0/1 in SQLite
819
- if (format === 'postgresql' && columnType === 'boolean') {
820
- return value === 1 ? 'TRUE' : 'FALSE';
821
- }
822
- return String(value);
823
- }
824
- // Handle booleans
825
- if (typeof value === 'boolean') {
826
- if (format === 'postgresql') {
827
- return value ? 'TRUE' : 'FALSE';
828
- }
829
- // MySQL and SQLite use 0/1
830
- return value ? '1' : '0';
831
- }
832
- // Handle Buffer (binary data)
833
- if (Buffer.isBuffer(value)) {
834
- if (format === 'postgresql') {
835
- // PostgreSQL bytea hex format
836
- return `'\\x${value.toString('hex')}'::bytea`;
837
- }
838
- // MySQL and SQLite hex format
839
- return `X'${value.toString('hex')}'`;
840
- }
841
- // Handle strings
842
- if (typeof value === 'string') {
843
- // Escape single quotes by doubling them
844
- const escaped = value.replace(/'/g, "''");
845
- // Also escape backslashes for MySQL
846
- const finalEscaped = format === 'mysql' ? escaped.replace(/\\/g, '\\\\') : escaped;
847
- return `'${finalEscaped}'`;
848
- }
849
- // Handle objects/arrays (JSON)
850
- if (typeof value === 'object') {
851
- const jsonStr = JSON.stringify(value).replace(/'/g, "''");
852
- return `'${jsonStr}'`;
853
- }
854
- // Fallback
855
- return 'NULL';
856
- }
857
- /**
858
- * Convert value with type-aware conversion for cross-database migration
859
- * Uses Knex columnInfo() metadata for accurate type detection
860
- *
861
- * @internal - Exported for testing only
862
- */
863
- export function convertValueWithType(value, columnName, columnInfo, // From knex(table).columnInfo()
864
- sourceFormat, targetFormat) {
865
- // Handle NULL
866
- if (value === null || value === undefined) {
867
- return 'NULL';
868
- }
869
- const colMeta = columnInfo.get(columnName);
870
- if (!colMeta) {
871
- // Fallback to basic formatValue
872
- return formatValue(value, targetFormat);
873
- }
874
- const colType = (colMeta.type || '').toLowerCase();
875
- // Boolean conversion - enhanced detection
876
- // Knex columnInfo types: 'boolean' (PostgreSQL), 'tinyint' (MySQL), 'integer' (SQLite boolean stored as 0/1)
877
- const isBooleanColumn = colType.includes('bool') ||
878
- colType === 'tinyint' ||
879
- colType === 'bit' ||
880
- colMeta.type === 'boolean' ||
881
- // Additional heuristic: maxLength === 1 for tinyint(1) in MySQL
882
- (colType === 'integer' && colMeta.maxLength === 1);
883
- if (isBooleanColumn) {
884
- // Normalize value to boolean
885
- const boolValue = Boolean(value);
886
- if (targetFormat === 'postgresql') {
887
- return boolValue ? 'TRUE' : 'FALSE';
888
- }
889
- // SQLite and MySQL use 0/1
890
- return boolValue ? '1' : '0';
891
- }
892
- // Timestamp/DateTime conversion - enhanced with columnInfo metadata
893
- const isTimestampColumn = colType.includes('timestamp') ||
894
- colType.includes('datetime') ||
895
- colType.includes('date') ||
896
- colType === 'time';
897
- if (isTimestampColumn) {
898
- if (typeof value === 'number') {
899
- // Unix timestamp - check if milliseconds or seconds based on magnitude
900
- const timestamp = value > 10000000000 ? value : value * 1000;
901
- const date = new Date(timestamp);
902
- // ISO 8601 format: YYYY-MM-DD HH:MM:SS
903
- const year = date.getUTCFullYear();
904
- const month = String(date.getUTCMonth() + 1).padStart(2, '0');
905
- const day = String(date.getUTCDate()).padStart(2, '0');
906
- const hours = String(date.getUTCHours()).padStart(2, '0');
907
- const minutes = String(date.getUTCMinutes()).padStart(2, '0');
908
- const seconds = String(date.getUTCSeconds()).padStart(2, '0');
909
- const isoString = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
910
- if (targetFormat === 'postgresql') {
911
- return `'${isoString}'::timestamp`;
912
- }
913
- else if (targetFormat === 'mysql') {
914
- return `'${isoString}'`;
915
- }
916
- return `'${isoString}'`;
917
- }
918
- else if (typeof value === 'string') {
919
- // Detect ISO 8601 format (e.g., '2025-11-05T00:07:53.343Z')
920
- // ISO 8601 pattern: YYYY-MM-DDTHH:MM:SS.sssZ or with timezone offset
921
- const iso8601Pattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?(Z|[+-]\d{2}:\d{2})?$/;
922
- if (iso8601Pattern.test(value)) {
923
- // Parse ISO 8601 string and convert to database-compatible format
924
- const date = new Date(value);
925
- const year = date.getUTCFullYear();
926
- const month = String(date.getUTCMonth() + 1).padStart(2, '0');
927
- const day = String(date.getUTCDate()).padStart(2, '0');
928
- const hours = String(date.getUTCHours()).padStart(2, '0');
929
- const minutes = String(date.getUTCMinutes()).padStart(2, '0');
930
- const seconds = String(date.getUTCSeconds()).padStart(2, '0');
931
- const isoString = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
932
- if (targetFormat === 'postgresql') {
933
- return `'${isoString}'::timestamp`;
934
- }
935
- else if (targetFormat === 'mysql') {
936
- return `'${isoString}'`;
937
- }
938
- return `'${isoString}'`;
939
- }
940
- // Already formatted string - ensure proper escaping
941
- const escaped = value.replace(/'/g, "''");
942
- if (targetFormat === 'postgresql') {
943
- return `'${escaped}'::timestamp`;
944
- }
945
- return `'${escaped}'`;
946
- }
947
- else if (value instanceof Date) {
948
- // Date object
949
- const year = value.getUTCFullYear();
950
- const month = String(value.getUTCMonth() + 1).padStart(2, '0');
951
- const day = String(value.getUTCDate()).padStart(2, '0');
952
- const hours = String(value.getUTCHours()).padStart(2, '0');
953
- const minutes = String(value.getUTCMinutes()).padStart(2, '0');
954
- const seconds = String(value.getUTCSeconds()).padStart(2, '0');
955
- const isoString = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
956
- if (targetFormat === 'postgresql') {
957
- return `'${isoString}'::timestamp`;
958
- }
959
- return `'${isoString}'`;
960
- }
961
- }
962
- // Binary/Buffer handling - enhanced with proper encoding
963
- const isBinaryColumn = colType.includes('blob') ||
964
- colType.includes('bytea') ||
965
- colType.includes('binary') ||
966
- colType.includes('varbinary');
967
- if (Buffer.isBuffer(value) || isBinaryColumn) {
968
- const bufferValue = Buffer.isBuffer(value) ? value : Buffer.from(value);
969
- const hexString = bufferValue.toString('hex');
970
- if (targetFormat === 'postgresql') {
971
- // PostgreSQL bytea hex format: '\x...'::bytea
972
- return `'\\x${hexString}'::bytea`;
973
- }
974
- else if (targetFormat === 'mysql') {
975
- // MySQL binary hex format: X'...' or 0x...
976
- return `X'${hexString}'`;
977
- }
978
- // SQLite hex format
979
- return `X'${hexString}'`;
980
- }
981
- // JSON handling - enhanced with proper type casting
982
- const isJsonColumn = colType.includes('json') ||
983
- colType === 'jsonb';
984
- if (isJsonColumn) {
985
- let jsonStr;
986
- if (typeof value === 'string') {
987
- // Already stringified by Knex - validate and escape
988
- try {
989
- JSON.parse(value); // Validate
990
- jsonStr = value.replace(/'/g, "''");
991
- }
992
- catch {
993
- // Invalid JSON string - treat as regular string
994
- jsonStr = JSON.stringify(value).replace(/'/g, "''");
995
- }
996
- }
997
- else if (typeof value === 'object') {
998
- // Object that needs stringification
999
- jsonStr = JSON.stringify(value).replace(/'/g, "''");
1000
- }
1001
- else {
1002
- // Primitive value - stringify
1003
- jsonStr = JSON.stringify(value).replace(/'/g, "''");
1004
- }
1005
- if (targetFormat === 'postgresql') {
1006
- // Use JSONB for better performance
1007
- return `'${jsonStr}'::jsonb`;
1008
- }
1009
- else if (targetFormat === 'mysql') {
1010
- // MySQL 5.7+ JSON type
1011
- return `'${jsonStr}'`;
1012
- }
1013
- // SQLite stores JSON as TEXT
1014
- return `'${jsonStr}'`;
1015
- }
1016
- // PostgreSQL Arrays - enhanced detection
1017
- const isArrayColumn = colType.includes('array') || colType.includes('[]');
1018
- if ((isArrayColumn || Array.isArray(value)) && targetFormat === 'postgresql') {
1019
- if (Array.isArray(value)) {
1020
- // Convert array elements recursively
1021
- const arrayStr = value
1022
- .map(v => {
1023
- if (v === null || v === undefined)
1024
- return 'NULL';
1025
- if (typeof v === 'string') {
1026
- const escaped = v.replace(/'/g, "''").replace(/\\/g, '\\\\');
1027
- return `'${escaped}'`;
1028
- }
1029
- if (typeof v === 'number')
1030
- return String(v);
1031
- if (typeof v === 'boolean')
1032
- return v ? 'TRUE' : 'FALSE';
1033
- // Objects - stringify
1034
- return `'${JSON.stringify(v).replace(/'/g, "''")}'`;
1035
- })
1036
- .join(',');
1037
- return `ARRAY[${arrayStr}]`;
1038
- }
1039
- else if (typeof value === 'string') {
1040
- // Already formatted array string - pass through
1041
- return value;
1042
- }
1043
- }
1044
- // PostgreSQL Enum types
1045
- const isEnumColumn = colType === 'enum' || colType.includes('user-defined');
1046
- if (isEnumColumn && targetFormat === 'postgresql') {
1047
- // Enum values must be quoted strings
1048
- const escaped = String(value).replace(/'/g, "''");
1049
- return `'${escaped}'`;
1050
- }
1051
- // Text columns with object values (fallback)
1052
- if (colType === 'text' && typeof value === 'object' && !Buffer.isBuffer(value)) {
1053
- const jsonStr = JSON.stringify(value).replace(/'/g, "''");
1054
- return `'${jsonStr}'`;
1055
- }
1056
- // Numeric types - ensure no quotes
1057
- const isNumericColumn = colType.includes('int') ||
1058
- colType.includes('decimal') ||
1059
- colType.includes('numeric') ||
1060
- colType.includes('real') ||
1061
- colType.includes('float') ||
1062
- colType.includes('double');
1063
- if (isNumericColumn && typeof value === 'number') {
1064
- return String(value);
1065
- }
1066
- // Fallback to basic formatValue
1067
- return formatValue(value, targetFormat);
1068
- }
1069
- /**
1070
- * Extract column names from INSERT SQL statement
1071
- * E.g., 'insert into "m_agents" ("id", "name", "is_reusable") values ...' => ["id", "name", "is_reusable"]
1072
- */
1073
- function extractColumnNamesFromInsertSql(sql) {
1074
- // Match: insert into "table" ("col1", "col2", "col3") values
1075
- // Or: insert into `table` (`col1`, `col2`) values
1076
- // Or: INSERT INTO table (col1, col2) VALUES
1077
- const match = sql.match(/insert\s+(?:ignore\s+)?into\s+[`"]?\w+[`"]?\s*\((.*?)\)\s*values/i);
1078
- if (!match) {
1079
- return [];
1080
- }
1081
- const columnsPart = match[1];
1082
- // Split by comma and extract column names (removing quotes and whitespace)
1083
- return columnsPart
1084
- .split(',')
1085
- .map(col => col.trim().replace(/[`"]/g, ''));
1086
- }
1087
- /**
1088
- * Embed bindings from Knex parameterized query into plain SQL
1089
- * with optional type-aware conversion for cross-database migrations
1090
- */
1091
- function embedBindings(sql, bindings, format, columnTypes, columnNames, columnInfo // NEW: columnInfo from knex(table).columnInfo()
1092
- ) {
1093
- // Detect source format (for now, assume SQLite as source)
1094
- // TODO: Make this configurable or detect from the knex instance
1095
- const sourceFormat = 'sqlite';
1096
- if (format === 'postgresql') {
1097
- // PostgreSQL: $1, $2, ... (replace in reverse order to avoid $10 matching $1)
1098
- let result = sql;
1099
- for (let i = bindings.length; i >= 1; i--) {
1100
- const placeholder = `$${i}`;
1101
- // For multi-row inserts, column names repeat: $1-$5 map to cols 0-4, $6-$10 map to cols 0-4, etc.
1102
- const columnIndex = columnNames && columnNames.length > 0 ? (i - 1) % columnNames.length : i - 1;
1103
- const columnName = columnNames?.[columnIndex] || '';
1104
- // Use new convertValueWithType with columnInfo if available
1105
- const value = columnInfo
1106
- ? convertValueWithType(bindings[i - 1], columnName, columnInfo, sourceFormat, format)
1107
- : formatValue(bindings[i - 1], format);
1108
- result = result.replace(new RegExp(`\\${placeholder}\\b`, 'g'), value);
1109
- }
1110
- return result;
1111
- }
1112
- else {
1113
- // MySQL/SQLite: ? placeholders
1114
- let result = sql;
1115
- let bindingIndex = 0;
1116
- result = result.replace(/\?/g, () => {
1117
- if (bindingIndex >= bindings.length) {
1118
- throw new Error(`Not enough bindings: ${bindings.length} provided, more needed`);
1119
- }
1120
- // For multi-row inserts, column names repeat
1121
- const columnIndex = columnNames && columnNames.length > 0 ? bindingIndex % columnNames.length : bindingIndex;
1122
- const columnName = columnNames?.[columnIndex] || '';
1123
- // Use new convertValueWithType with columnInfo if available
1124
- const value = columnInfo
1125
- ? convertValueWithType(bindings[bindingIndex], columnName, columnInfo, sourceFormat, format)
1126
- : formatValue(bindings[bindingIndex], format);
1127
- bindingIndex++;
1128
- return value;
1129
- });
1130
- return result;
1131
- }
1132
- }
1133
- /**
1134
- * Create a throwaway Knex instance for SQL generation
1135
- */
1136
- function createKnexForFormat(format) {
1137
- const client = format === 'mysql' ? 'mysql2' : format === 'postgresql' ? 'pg' : 'better-sqlite3';
1138
- return knex({
1139
- client,
1140
- connection: client === 'better-sqlite3' ? { filename: ':memory:' } : {},
1141
- useNullAsDefault: client === 'better-sqlite3',
1142
- });
1143
- }
1144
- /**
1145
- * Generate a bulk INSERT statement for a table with conflict resolution
1146
- *
1147
- * REFACTORED: Uses Knex query builder instead of manual string construction
1148
- */
1149
- export function generateBulkInsert(table, rows, format, options = {}) {
1150
- if (rows.length === 0) {
1151
- return [];
1152
- }
1153
- const { chunkSize = 100, conflictMode = 'error', primaryKeys = [], columnTypes, columnInfo, } = options;
1154
- const statements = [];
1155
- const targetKnex = createKnexForFormat(format);
1156
- try {
1157
- // Split into chunks to avoid too-large statements
1158
- for (let i = 0; i < rows.length; i += chunkSize) {
1159
- const chunk = rows.slice(i, i + chunkSize);
1160
- // Use Knex to generate parameterized INSERT
1161
- let builder = targetKnex(table).insert(chunk);
1162
- // Handle conflict modes with Knex-specific methods
1163
- if (conflictMode === 'ignore') {
1164
- if (format === 'mysql') {
1165
- // MySQL: INSERT IGNORE is handled via raw SQL modification
1166
- const { sql, bindings } = builder.toSQL().toNative();
1167
- const ignoreSql = sql.replace(/^insert into/i, 'INSERT IGNORE INTO');
1168
- const columnNames = extractColumnNamesFromInsertSql(ignoreSql);
1169
- const embedded = embedBindings(ignoreSql, bindings, format, columnTypes, columnNames, columnInfo);
1170
- statements.push(embedded + ';');
1171
- continue;
1172
- }
1173
- else if (format === 'postgresql') {
1174
- // PostgreSQL: ON CONFLICT DO NOTHING
1175
- // Note: Knex's onConflict() requires specifying columns, so we use raw SQL
1176
- const { sql, bindings } = builder.toSQL().toNative();
1177
- const conflictSql = sql + ' ON CONFLICT DO NOTHING';
1178
- const columnNames = extractColumnNamesFromInsertSql(conflictSql);
1179
- const embedded = embedBindings(conflictSql, bindings, format, columnTypes, columnNames, columnInfo);
1180
- statements.push(embedded + ';');
1181
- continue;
1182
- }
1183
- else {
1184
- // SQLite: INSERT OR IGNORE
1185
- const { sql, bindings } = builder.toSQL().toNative();
1186
- const ignoreSql = sql.replace(/^insert into/i, 'INSERT OR IGNORE INTO');
1187
- const columnNames = extractColumnNamesFromInsertSql(ignoreSql);
1188
- const embedded = embedBindings(ignoreSql, bindings, format, columnTypes, columnNames, columnInfo);
1189
- statements.push(embedded + ';');
1190
- continue;
1191
- }
1192
- }
1193
- else if (conflictMode === 'replace') {
1194
- // REPLACE mode requires primary keys
1195
- if (primaryKeys.length === 0) {
1196
- throw new Error(`Cannot use 'replace' mode for table ${table}: no primary key found`);
1197
- }
1198
- const { sql, bindings } = builder.toSQL().toNative();
1199
- const columns = Object.keys(chunk[0]);
1200
- const nonPkColumns = columns.filter(col => !primaryKeys.includes(col));
1201
- const columnNames = extractColumnNamesFromInsertSql(sql);
1202
- if (format === 'mysql') {
1203
- // MySQL: ON DUPLICATE KEY UPDATE
1204
- const updateClauses = nonPkColumns.map(col => `${quoteIdentifier(col, format)} = VALUES(${quoteIdentifier(col, format)})`);
1205
- const finalSql = `${sql}\nON DUPLICATE KEY UPDATE\n ${updateClauses.join(',\n ')}`;
1206
- const embedded = embedBindings(finalSql, bindings, format, columnTypes, columnNames, columnInfo);
1207
- statements.push(embedded + ';');
1208
- }
1209
- else if (format === 'postgresql') {
1210
- // PostgreSQL: ON CONFLICT DO UPDATE
1211
- const quotedPks = primaryKeys.map(pk => quoteIdentifier(pk, format));
1212
- const updateClauses = nonPkColumns.map(col => `${quoteIdentifier(col, format)} = EXCLUDED.${quoteIdentifier(col, format)}`);
1213
- const finalSql = `${sql}\nON CONFLICT (${quotedPks.join(', ')}) DO UPDATE SET\n ${updateClauses.join(',\n ')}`;
1214
- const embedded = embedBindings(finalSql, bindings, format, columnTypes, columnNames, columnInfo);
1215
- statements.push(embedded + ';');
1216
- }
1217
- else {
1218
- // SQLite: ON CONFLICT DO UPDATE
1219
- const quotedPks = primaryKeys.map(pk => quoteIdentifier(pk, format));
1220
- const updateClauses = nonPkColumns.map(col => `${quoteIdentifier(col, format)} = excluded.${quoteIdentifier(col, format)}`);
1221
- const finalSql = `${sql}\nON CONFLICT (${quotedPks.join(', ')}) DO UPDATE SET\n ${updateClauses.join(',\n ')}`;
1222
- const embedded = embedBindings(finalSql, bindings, format, columnTypes, columnNames, columnInfo);
1223
- statements.push(embedded + ';');
1224
- }
1225
- }
1226
- else {
1227
- // ERROR mode: Standard INSERT
1228
- const { sql, bindings } = builder.toSQL().toNative();
1229
- const columnNames = extractColumnNamesFromInsertSql(sql);
1230
- const embedded = embedBindings(sql, bindings, format, columnTypes, columnNames, columnInfo);
1231
- statements.push(embedded + ';');
1232
- }
1233
- }
1234
- return statements;
1235
- }
1236
- finally {
1237
- // Clean up Knex instance
1238
- targetKnex.destroy();
1239
- }
1240
- }
1241
- /**
1242
- * Generate header comments for SQL dump
1243
- */
1244
- export function generateHeader(format) {
1245
- const timestamp = new Date().toISOString();
1246
- return `-- SQL Dump generated by sqlew
1247
- -- Date: ${timestamp}
1248
- -- Target: ${format.toUpperCase()}
1249
- --
1250
- -- This dump is wrapped in a transaction.
1251
- -- On error, all changes will be rolled back automatically.
1252
- --
1253
- -- Usage (empty database):
1254
- -- ${format === 'mysql' ? 'mysql mydb < dump.sql' : format === 'postgresql' ? 'psql -d mydb -f dump.sql' : 'sqlite3 mydb.db < dump.sql'}
1255
-
1256
- `;
1257
- }
1258
- /**
1259
- * Generate foreign key disable/enable statements
1260
- */
1261
- export function generateForeignKeyControls(format, enable) {
1262
- if (format === 'mysql') {
1263
- return enable
1264
- ? 'SET FOREIGN_KEY_CHECKS=1;'
1265
- : 'SET FOREIGN_KEY_CHECKS=0;';
1266
- }
1267
- else if (format === 'postgresql') {
1268
- return enable
1269
- ? 'SET session_replication_role = DEFAULT;'
1270
- : 'SET session_replication_role = replica;';
1271
- }
1272
- else {
1273
- // SQLite
1274
- return enable
1275
- ? 'PRAGMA foreign_keys = ON;'
1276
- : 'PRAGMA foreign_keys = OFF;';
1277
- }
1278
- }
1279
- /**
1280
- * Generate transaction control statements
1281
- */
1282
- export function generateTransactionControl(format, isStart) {
1283
- if (isStart) {
1284
- return format === 'mysql' ? 'START TRANSACTION;'
1285
- : format === 'postgresql' ? 'BEGIN;'
1286
- : 'BEGIN TRANSACTION;';
1287
- }
1288
- else {
1289
- return 'COMMIT;';
1290
- }
1291
- }
1292
- /**
1293
- * Generate sequence reset statements for PostgreSQL
1294
- */
1295
- export async function generateSequenceResets(knex, tables) {
1296
- const statements = [];
1297
- for (const table of tables) {
1298
- try {
1299
- // Check if table has an id column with a sequence
1300
- const result = await knex.raw(`
1301
- SELECT column_name, column_default
1302
- FROM information_schema.columns
1303
- WHERE table_name = ?
1304
- AND column_default LIKE 'nextval%'
1305
- `, [table]);
1306
- if (result.rows.length > 0) {
1307
- const columnName = result.rows[0].column_name;
1308
- const sequenceName = `${table}_${columnName}_seq`;
1309
- statements.push(`SELECT setval('${sequenceName}', COALESCE((SELECT MAX(${columnName}) FROM "${table}"), 1), true);`);
1310
- }
1311
- }
1312
- catch (err) {
1313
- // Ignore errors for tables without sequences
1314
- }
1315
- }
1316
- return statements;
1317
- }
1318
- /**
1319
- * Get foreign key dependencies for tables
1320
- * Returns a map of table -> array of tables it depends on
1321
- *
1322
- * @internal Exported for testing purposes
1323
- */
1324
- export async function getTableDependencies(knex, tables) {
1325
- const dependencies = new Map();
1326
- const client = knex.client.config.client;
1327
- for (const table of tables) {
1328
- dependencies.set(table, []);
1329
- }
1330
- for (const table of tables) {
1331
- try {
1332
- if (client === 'better-sqlite3' || client === 'sqlite3') {
1333
- // SQLite: Use PRAGMA foreign_key_list() for reliable FK detection
1334
- // This catches both inline REFERENCES and explicit FOREIGN KEY syntax
1335
- const result = await knex.raw(`PRAGMA foreign_key_list(${table})`);
1336
- const fkList = Array.isArray(result) ? result : [];
1337
- for (const fk of fkList) {
1338
- const referencedTable = fk.table;
1339
- if (tables.includes(referencedTable) && referencedTable !== table) {
1340
- dependencies.get(table).push(referencedTable);
1341
- }
1342
- }
1343
- }
1344
- else if (client === 'mysql' || client === 'mysql2') {
1345
- // MySQL: Use information_schema
1346
- const result = await knex.raw(`
1347
- SELECT REFERENCED_TABLE_NAME
1348
- FROM information_schema.KEY_COLUMN_USAGE
1349
- WHERE TABLE_SCHEMA = DATABASE()
1350
- AND TABLE_NAME = ?
1351
- AND REFERENCED_TABLE_NAME IS NOT NULL
1352
- `, [table]);
1353
- for (const row of result[0]) {
1354
- const referencedTable = row.REFERENCED_TABLE_NAME;
1355
- if (tables.includes(referencedTable) && referencedTable !== table) {
1356
- dependencies.get(table).push(referencedTable);
1357
- }
1358
- }
1359
- }
1360
- else if (client === 'pg') {
1361
- // PostgreSQL: Use information_schema
1362
- const result = await knex.raw(`
1363
- SELECT DISTINCT ccu.table_name AS referenced_table
1364
- FROM information_schema.table_constraints AS tc
1365
- JOIN information_schema.key_column_usage AS kcu
1366
- ON tc.constraint_name = kcu.constraint_name
1367
- AND tc.table_schema = kcu.table_schema
1368
- JOIN information_schema.constraint_column_usage AS ccu
1369
- ON ccu.constraint_name = tc.constraint_name
1370
- AND ccu.table_schema = tc.table_schema
1371
- WHERE tc.constraint_type = 'FOREIGN KEY'
1372
- AND tc.table_name = ?
1373
- `, [table]);
1374
- for (const row of result.rows) {
1375
- const referencedTable = row.referenced_table;
1376
- if (tables.includes(referencedTable) && referencedTable !== table) {
1377
- dependencies.get(table).push(referencedTable);
1378
- }
1379
- }
1380
- }
1381
- }
1382
- catch (err) {
1383
- // Ignore errors - table might not have foreign keys
1384
- }
1385
- }
1386
- return dependencies;
1387
- }
1388
- /**
1389
- * Topologically sort tables by foreign key dependencies
1390
- * Returns tables in order where parent tables come before child tables
1391
- *
1392
- * @internal Exported for testing purposes
1393
- */
1394
- export function topologicalSort(tables, dependencies) {
1395
- const sorted = [];
1396
- const visited = new Set();
1397
- const visiting = new Set();
1398
- function visit(table) {
1399
- if (visited.has(table))
1400
- return;
1401
- if (visiting.has(table)) {
1402
- // Circular dependency detected - log warning and continue
1403
- debugLog('WARN', `Circular foreign key dependency detected involving table: ${table}`);
1404
- return;
1405
- }
1406
- visiting.add(table);
1407
- const deps = dependencies.get(table) || [];
1408
- for (const dep of deps) {
1409
- visit(dep);
1410
- }
1411
- visiting.delete(table);
1412
- visited.add(table);
1413
- sorted.push(table);
1414
- }
1415
- for (const table of tables) {
1416
- visit(table);
1417
- }
1418
- return sorted;
1419
- }
1420
- /**
1421
- * Main function to generate complete SQL dump
1422
- */
1423
- export async function generateSqlDump(knex, format, options = {}) {
1424
- const { tables: requestedTables, includeHeader = true, includeSchema = true, // Default to TRUE - include schema
1425
- chunkSize = 100, conflictMode = 'error' } = options;
1426
- const statements = [];
1427
- // Add header
1428
- if (includeHeader) {
1429
- statements.push(generateHeader(format));
1430
- }
1431
- // Disable foreign key checks
1432
- statements.push(generateForeignKeyControls(format, false));
1433
- statements.push('');
1434
- // Start transaction
1435
- statements.push(generateTransactionControl(format, true));
1436
- statements.push('');
1437
- // Get tables to dump
1438
- // Include knex_migrations table when schema is included for complete migration state
1439
- const allTables = await getAllTables(knex, includeSchema);
1440
- const tablesToDump = requestedTables
1441
- ? allTables.filter(t => requestedTables.includes(t))
1442
- : allTables;
1443
- // Sort tables by foreign key dependencies for PostgreSQL compatibility
1444
- // Parent tables must be created before child tables
1445
- const dependencies = await getTableDependencies(knex, tablesToDump);
1446
- const sortedTables = topologicalSort(tablesToDump, dependencies);
1447
- // Generate CREATE TABLE statements if schema is included
1448
- if (includeSchema) {
1449
- statements.push('-- ============================================');
1450
- statements.push('-- Schema (CREATE TABLE statements)');
1451
- statements.push('-- ============================================');
1452
- statements.push('');
1453
- for (const table of sortedTables) {
1454
- try {
1455
- const createSql = await getCreateTableStatement(knex, table, format);
1456
- statements.push(`-- Table: ${table}`);
1457
- statements.push(createSql);
1458
- statements.push('');
1459
- }
1460
- catch (err) {
1461
- console.warn(`Warning: Could not get CREATE TABLE for ${table}:`, err);
1462
- statements.push(`-- Warning: Could not create table ${table}`);
1463
- statements.push('');
1464
- }
1465
- }
1466
- // Generate CREATE VIEW statements
1467
- try {
1468
- const views = await getAllViews(knex);
1469
- if (views.length > 0) {
1470
- statements.push('-- ============================================');
1471
- statements.push('-- Views');
1472
- statements.push('-- ============================================');
1473
- statements.push('');
1474
- for (const view of views) {
1475
- try {
1476
- const createViewSql = await getCreateViewStatement(knex, view, format);
1477
- statements.push(`-- View: ${view}`);
1478
- statements.push(createViewSql);
1479
- statements.push('');
1480
- }
1481
- catch (err) {
1482
- console.warn(`Warning: Could not get CREATE VIEW for ${view}:`, err);
1483
- statements.push(`-- Warning: Could not create view ${view}`);
1484
- statements.push('');
1485
- }
1486
- }
1487
- }
1488
- }
1489
- catch (err) {
1490
- console.warn('Warning: Could not retrieve views:', err);
1491
- }
1492
- // Generate CREATE INDEX statements
1493
- try {
1494
- const indexStatements = [];
1495
- for (const table of sortedTables) {
1496
- const indexes = await getAllIndexes(knex, table);
1497
- if (indexes.length > 0) {
1498
- for (const indexName of indexes) {
1499
- try {
1500
- const createIndexSql = await getCreateIndexStatement(knex, indexName, format);
1501
- indexStatements.push(`-- Index: ${indexName} on ${table}`);
1502
- indexStatements.push(createIndexSql);
1503
- indexStatements.push('');
1504
- }
1505
- catch (err) {
1506
- console.warn(`Warning: Could not get CREATE INDEX for ${indexName}:`, err);
1507
- }
1508
- }
1509
- }
1510
- }
1511
- if (indexStatements.length > 0) {
1512
- statements.push('-- ============================================');
1513
- statements.push('-- Indexes');
1514
- statements.push('-- ============================================');
1515
- statements.push('');
1516
- statements.push(...indexStatements);
1517
- }
1518
- }
1519
- catch (err) {
1520
- console.warn('Warning: Could not retrieve indexes:', err);
1521
- }
1522
- statements.push('-- ============================================');
1523
- statements.push('-- Data (INSERT statements)');
1524
- statements.push('-- ============================================');
1525
- statements.push('');
1526
- }
1527
- // Generate INSERT statements for each table (in dependency order)
1528
- // Skip data insertion if chunkSize is 0 (schema-only mode)
1529
- if (chunkSize > 0) {
1530
- for (const table of sortedTables) {
1531
- statements.push(`-- Data for table: ${table}`);
1532
- const rows = await knex(table).select('*');
1533
- if (rows.length === 0) {
1534
- statements.push(`-- No data in table ${table}`);
1535
- statements.push('');
1536
- continue;
1537
- }
1538
- // Get column types for cross-database type conversion
1539
- // Query from source database to understand original types (e.g., INTEGER for booleans in SQLite)
1540
- let columnTypes = new Map();
1541
- let columnInfoMap = new Map();
1542
- try {
1543
- const columnInfo = await knex(table).columnInfo();
1544
- for (const [col, info] of Object.entries(columnInfo)) {
1545
- columnTypes.set(col, info.type);
1546
- columnInfoMap.set(col, info); // Store full column metadata
1547
- }
1548
- }
1549
- catch (err) {
1550
- console.warn(`Warning: Could not get column types for table ${table}:`, err);
1551
- }
1552
- // Get primary keys if using replace mode
1553
- let primaryKeys = [];
1554
- if (conflictMode === 'replace') {
1555
- try {
1556
- primaryKeys = await getPrimaryKeyColumns(knex, table);
1557
- if (primaryKeys.length > 0) {
1558
- statements.push(`-- Primary key(s): ${primaryKeys.join(', ')}`);
1559
- }
1560
- }
1561
- catch (err) {
1562
- console.warn(`Warning: Could not detect primary key for table ${table}:`, err);
1563
- }
1564
- }
1565
- const inserts = generateBulkInsert(table, rows, format, {
1566
- chunkSize,
1567
- conflictMode,
1568
- primaryKeys,
1569
- columnTypes,
1570
- columnInfo: columnInfoMap // Pass full columnInfo for type-aware conversion
1571
- });
1572
- statements.push(...inserts);
1573
- statements.push('');
1574
- }
1575
- } // End of if (chunkSize > 0)
1576
- // Reset sequences for PostgreSQL
1577
- if (format === 'postgresql') {
1578
- statements.push('-- Reset sequences');
1579
- const sequenceResets = await generateSequenceResets(knex, tablesToDump);
1580
- statements.push(...sequenceResets);
1581
- statements.push('');
1582
- }
1583
- // Commit transaction
1584
- statements.push(generateTransactionControl(format, false));
1585
- statements.push('');
1586
- // Re-enable foreign key checks
1587
- statements.push(generateForeignKeyControls(format, true));
1588
- return statements.join('\n');
1589
- }
1590
- //# sourceMappingURL=sql-dump.js.map