@restforgejs/platform 4.1.1 → 4.3.1

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 (340) hide show
  1. package/SECURITY.md +83 -4
  2. package/bin/sdf-tools.exe +0 -0
  3. package/build-info.json +2 -2
  4. package/cli/consumer-deploy.js +1 -1
  5. package/cli/consumer.js +1 -1
  6. package/generators/cli/dashboard/create.js +4 -1
  7. package/generators/cli/endpoint/create.js +43 -4
  8. package/generators/cli/key/generate.js +2 -1
  9. package/generators/cli/key/revoke.js +2 -1
  10. package/generators/cli/payload/diff.js +3 -2
  11. package/generators/cli/payload/generate.js +3 -2
  12. package/generators/cli/payload/sync.js +3 -2
  13. package/generators/cli/payload/validate.js +3 -2
  14. package/generators/cli/processor/create.js +14 -3
  15. package/generators/cli/project/delete.js +2 -1
  16. package/generators/cli/query/validate.js +3 -2
  17. package/generators/cli/schema/apply.js +526 -0
  18. package/generators/cli/schema/describe.js +3 -2
  19. package/generators/cli/schema/diff.js +322 -0
  20. package/generators/cli/schema/generate-ddl.js +7 -10
  21. package/generators/cli/schema/init.js +95 -172
  22. package/generators/cli/schema/introspect.js +3 -2
  23. package/generators/cli/schema/list.js +3 -2
  24. package/generators/cli/schema/migrate.js +13 -18
  25. package/generators/cli/schema/models.js +8 -12
  26. package/generators/cli/schema/template.js +222 -0
  27. package/generators/cli/schema/validate.js +8 -12
  28. package/generators/cli-entry.js +17 -2
  29. package/generators/lib/dbschema-kit/apply-engine.js +582 -0
  30. package/generators/lib/dbschema-kit/diff-engine.js +703 -0
  31. package/generators/lib/dbschema-kit/diff-reporter.js +272 -0
  32. package/generators/lib/dbschema-kit/emitters/alter-table.js +275 -0
  33. package/generators/lib/migration/audit-table-runner.js +213 -215
  34. package/generators/lib/payload/endpoint-schema-validator.js +171 -0
  35. package/generators/lib/payload/payload-runner.js +137 -220
  36. package/generators/lib/payload/schema-diff.js +277 -0
  37. package/generators/lib/templates/dashboard-catalog.js +1 -437
  38. package/generators/lib/templates/db-connection-env.js +1 -212
  39. package/generators/lib/templates/dbschema-catalog.js +1 -489
  40. package/generators/lib/templates/field-validation-catalog.js +1 -531
  41. package/generators/lib/templates/mysql-template.js +1 -3863
  42. package/generators/lib/templates/oracle-template.js +1 -3915
  43. package/generators/lib/templates/postgres-template.js +1 -5838
  44. package/generators/lib/templates/query-declarative-catalog.js +1 -199
  45. package/generators/lib/templates/sqlite-template.js +1 -3440
  46. package/generators/lib/utils/audit-columns.js +181 -0
  47. package/generators/lib/utils/cli-output.js +17 -0
  48. package/generators/lib/utils/database-introspector.js +16 -13
  49. package/generators/lib/utils/env-manager.js +6 -0
  50. package/generators/lib/utils/path-validator.js +71 -0
  51. package/generators/lib/validators/payload-validator.js +1 -2
  52. package/integrity-manifest.json +28 -10
  53. package/package.json +11 -3
  54. package/scripts/verify-integrity.js +1 -1
  55. package/server.js +1 -1
  56. package/src/components/handlers/adjust_handler.js +1 -1
  57. package/src/components/handlers/audit_handler.js +1 -1
  58. package/src/components/handlers/delete_handler.js +1 -1
  59. package/src/components/handlers/export_handler.js +1 -1
  60. package/src/components/handlers/import_handler.js +1 -1
  61. package/src/components/handlers/insert_handler.js +1 -1
  62. package/src/components/handlers/update_handler.js +1 -1
  63. package/src/components/handlers/upload_handler.js +1 -1
  64. package/src/components/handlers/workflow_handler.js +1 -1
  65. package/src/components/integrations/webhook.js +1 -1
  66. package/src/consumers/baseConsumer.js +1 -1
  67. package/src/consumers/declarativeMapper.js +1 -1
  68. package/src/consumers/handlers/apiHandler.js +1 -1
  69. package/src/consumers/handlers/consoleHandler.js +1 -1
  70. package/src/consumers/handlers/databaseHandler.js +1 -1
  71. package/src/consumers/handlers/index.js +1 -1
  72. package/src/consumers/handlers/kafkaHandler.js +1 -1
  73. package/src/consumers/index.js +1 -1
  74. package/src/consumers/messageTransformer.js +1 -1
  75. package/src/consumers/validator.js +1 -1
  76. package/src/core/db/dialect/base-dialect.js +1 -1
  77. package/src/core/db/dialect/index.js +1 -1
  78. package/src/core/db/dialect/mysql-dialect.js +1 -1
  79. package/src/core/db/dialect/oracle-dialect.js +1 -1
  80. package/src/core/db/dialect/postgres-dialect.js +1 -1
  81. package/src/core/db/dialect/sqlite-dialect.js +1 -1
  82. package/src/core/db/flatten-helper.js +1 -1
  83. package/src/core/db/query-builder-error.js +1 -1
  84. package/src/core/db/query-builder.js +1 -1
  85. package/src/core/db/relation-helper.js +1 -1
  86. package/src/core/handlers/delete_handler.js +1 -1
  87. package/src/core/handlers/insert_handler.js +1 -1
  88. package/src/core/handlers/update_handler.js +1 -1
  89. package/src/core/models/base-model.js +1 -1
  90. package/src/core/utils/cache-manager.js +1 -1
  91. package/src/core/utils/component-engine.js +1 -1
  92. package/src/core/utils/context-builder.js +1 -1
  93. package/src/core/utils/datetime-formatter.js +1 -1
  94. package/src/core/utils/datetime-parser.js +1 -1
  95. package/src/core/utils/db.js +1 -1
  96. package/src/core/utils/logger.js +1 -1
  97. package/src/core/utils/payload-loader.js +1 -1
  98. package/src/core/utils/security-checks.js +1 -1
  99. package/src/middleware/body-options.js +1 -1
  100. package/src/middleware/cors.js +1 -1
  101. package/src/middleware/idempotency.js +1 -1
  102. package/src/middleware/rate-limiter.js +1 -1
  103. package/src/middleware/request-logger.js +1 -1
  104. package/src/middleware/security-headers.js +1 -1
  105. package/src/models/base-model-mysql.js +1 -1
  106. package/src/models/base-model-oracle.js +1 -1
  107. package/src/models/base-model-sqlite.js +1 -1
  108. package/src/models/base-model.js +1 -1
  109. package/src/pro/caching/redis-client.js +1 -1
  110. package/src/pro/caching/redis-helper.js +1 -1
  111. package/src/pro/consumers/baseConsumer.js +1 -1
  112. package/src/pro/consumers/declarativeMapper.js +1 -1
  113. package/src/pro/consumers/handlers/apiHandler.js +1 -1
  114. package/src/pro/consumers/handlers/consoleHandler.js +1 -1
  115. package/src/pro/consumers/handlers/databaseHandler.js +1 -1
  116. package/src/pro/consumers/handlers/index.js +1 -1
  117. package/src/pro/consumers/handlers/kafkaHandler.js +1 -1
  118. package/src/pro/consumers/index.js +1 -1
  119. package/src/pro/consumers/messageTransformer.js +1 -1
  120. package/src/pro/consumers/validator.js +1 -1
  121. package/src/pro/database/base-model-mysql.js +1 -1
  122. package/src/pro/database/base-model-oracle.js +1 -1
  123. package/src/pro/database/base-model-sqlite.js +1 -1
  124. package/src/pro/database/db-mysql.js +1 -1
  125. package/src/pro/database/db-oracle.js +1 -1
  126. package/src/pro/database/db-sqlite.js +1 -1
  127. package/src/pro/excel/excel-generator.js +1 -1
  128. package/src/pro/excel/excel-parser.js +1 -1
  129. package/src/pro/excel/export-service.js +1 -1
  130. package/src/pro/excel/export_handler.js +1 -1
  131. package/src/pro/excel/import-service.js +1 -1
  132. package/src/pro/excel/import-validator.js +1 -1
  133. package/src/pro/excel/import_handler.js +1 -1
  134. package/src/pro/excel/upsert-builder.js +1 -1
  135. package/src/pro/idgen/idgen-routes.js +1 -1
  136. package/src/pro/integrations/lookup-resolver.js +1 -1
  137. package/src/pro/integrations/upload-handler-v2.js +1 -1
  138. package/src/pro/integrations/upload-handler.js +1 -1
  139. package/src/pro/integrations/webhook.js +1 -1
  140. package/src/pro/locking/lock-routes.js +1 -1
  141. package/src/pro/locking/resource-lock-manager.js +1 -1
  142. package/src/pro/messaging/kafkaConsumerService.js +1 -1
  143. package/src/pro/messaging/kafkaService.js +1 -1
  144. package/src/pro/messaging/messagehubService.js +1 -1
  145. package/src/pro/messaging/rabbitmqService.js +1 -1
  146. package/src/pro/scheduler/job-manager.js +1 -1
  147. package/src/pro/scheduler/job-routes.js +1 -1
  148. package/src/pro/scheduler/job-validator.js +1 -1
  149. package/src/pro/storage/base-storage-provider.js +1 -1
  150. package/src/pro/storage/file-metadata-helper.js +1 -1
  151. package/src/pro/storage/index.js +1 -1
  152. package/src/pro/storage/local-storage-provider.js +1 -1
  153. package/src/pro/storage/s3-storage-provider.js +1 -1
  154. package/src/pro/storage/upload-cleanup-job.js +1 -1
  155. package/src/pro/storage/upload-cleanup-scheduler.js +1 -1
  156. package/src/pro/storage/upload-pending-tracker.js +1 -1
  157. package/src/pro/websocket/broadcast-helper.js +1 -1
  158. package/src/pro/websocket/index.js +1 -1
  159. package/src/pro/websocket/livesync-server.js +1 -1
  160. package/src/pro/websocket/ws-broadcaster.js +1 -1
  161. package/src/services/export-service.js +1 -1
  162. package/src/services/import-service.js +1 -1
  163. package/src/services/kafkaConsumerService.js +1 -1
  164. package/src/services/kafkaService.js +1 -1
  165. package/src/services/messagehubService.js +1 -1
  166. package/src/services/rabbitmqService.js +1 -1
  167. package/src/utils/cache-invalidation-registry.js +1 -1
  168. package/src/utils/cache-manager.js +1 -1
  169. package/src/utils/component-engine.js +1 -1
  170. package/src/utils/config-extractor.js +1 -1
  171. package/src/utils/consumerLogger.js +1 -1
  172. package/src/utils/context-builder.js +1 -1
  173. package/src/utils/dashboard-helpers.js +1 -1
  174. package/src/utils/dateHelper.js +1 -1
  175. package/src/utils/datetime-formatter.js +1 -1
  176. package/src/utils/datetime-parser.js +1 -1
  177. package/src/utils/db-bootstrap.js +1 -1
  178. package/src/utils/db-mysql.js +1 -1
  179. package/src/utils/db-oracle.js +1 -1
  180. package/src/utils/db-sqlite.js +1 -1
  181. package/src/utils/db.js +1 -1
  182. package/src/utils/demo-generator.js +1 -1
  183. package/src/utils/excel-generator.js +1 -1
  184. package/src/utils/excel-parser.js +1 -1
  185. package/src/utils/file-watcher.js +1 -1
  186. package/src/utils/id-generator.js +1 -1
  187. package/src/utils/idempotency-manager.js +1 -1
  188. package/src/utils/import-validator.js +1 -1
  189. package/src/utils/license-client.js +1 -1
  190. package/src/utils/lock-manager.js +1 -1
  191. package/src/utils/logger.js +1 -1
  192. package/src/utils/lookup-resolver.js +1 -1
  193. package/src/utils/payload-loader.js +1 -1
  194. package/src/utils/processor-response.js +1 -1
  195. package/src/utils/rabbitmq.js +1 -1
  196. package/src/utils/redis-client.js +1 -1
  197. package/src/utils/redis-helper.js +1 -1
  198. package/src/utils/request-scope.js +1 -1
  199. package/src/utils/security-checks.js +1 -1
  200. package/src/utils/service-resolver.js +1 -1
  201. package/src/utils/shutdown-coordinator.js +1 -1
  202. package/src/utils/trusted-keys.js +1 -1
  203. package/src/utils/upload-handler.js +1 -1
  204. package/src/utils/upsert-builder.js +1 -1
  205. package/src/utils/workflow-hook-executor.js +1 -1
  206. package/generators/metadata/global.json +0 -58
  207. package/generators/metadata/test-mysql-workbench.json +0 -118
  208. package/generators/metadata/test-mysql.json +0 -56
  209. package/generators/metadata/test-oracle-workbench.json +0 -118
  210. package/generators/metadata/test-oracle.json +0 -56
  211. package/generators/metadata/test-pg-workbench.json +0 -118
  212. package/generators/metadata/test-pg.json +0 -56
  213. package/generators/scripts/obfuscate-source.js +0 -356
  214. package/generators/scripts/validate-catalog.js +0 -430
  215. package/generators/scripts/validate-dbschema-catalog.js +0 -708
  216. package/generators/tests/baseline/mysql/mini_inventory_item/src/models/mini-inventory/item.js +0 -944
  217. package/generators/tests/baseline/mysql/mini_inventory_item/src/modules/mini-inventory/item.js +0 -740
  218. package/generators/tests/baseline/mysql/mini_inventory_item/src/modules/mini-inventory.js +0 -336
  219. package/generators/tests/baseline/oracle/mini_inventory_item/src/models/mini-inventory/item.js +0 -1002
  220. package/generators/tests/baseline/oracle/mini_inventory_item/src/modules/mini-inventory/item.js +0 -740
  221. package/generators/tests/baseline/oracle/mini_inventory_item/src/modules/mini-inventory.js +0 -336
  222. package/generators/tests/baseline/postgres/mini_inventory_item/src/models/mini-inventory/item.js +0 -1333
  223. package/generators/tests/baseline/postgres/mini_inventory_item/src/modules/mini-inventory/item.js +0 -1173
  224. package/generators/tests/baseline/postgres/mini_inventory_item/src/modules/mini-inventory.js +0 -496
  225. package/generators/tests/fixtures/payloads/custom-sensitive.json +0 -27
  226. package/generators/tests/fixtures/payloads/dynamic-search-optout.json +0 -23
  227. package/generators/tests/fixtures/payloads/login-with-password.json +0 -22
  228. package/generators/tests/fixtures/payloads/order-process.json +0 -52
  229. package/generators/tests/fixtures/payloads/with-inline-sql.json +0 -26
  230. package/generators/tests/integration-tahap4b/README.md +0 -145
  231. package/generators/tests/integration-tahap4b/run-concurrent.js +0 -77
  232. package/generators/tests/integration-tahap4b/seed.sql +0 -53
  233. package/generators/tests/integration-tahap4b/verify.sql +0 -110
  234. package/generators/tests/unit/cli/create-dashboard.test.js +0 -505
  235. package/generators/tests/unit/cli/create-processor.test.js +0 -319
  236. package/generators/tests/unit/cli/dispatch-dashboard.test.js +0 -149
  237. package/generators/tests/unit/lib/dashboard-generator.test.js +0 -895
  238. package/generators/tests/unit/lib/dashboard-validator.test.js +0 -354
  239. package/generators/tests/unit/lib/dbschema-kit/apply-executor.test.js +0 -437
  240. package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-introspect.test.js +0 -393
  241. package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-generate-ddl.test.js +0 -104
  242. package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-init.test.js +0 -119
  243. package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-list.test.js +0 -48
  244. package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-migrate.test.js +0 -175
  245. package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-validate.test.js +0 -102
  246. package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-models.test.js +0 -43
  247. package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/all-schemas-listing.js +0 -84
  248. package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/connection-error.js +0 -13
  249. package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/empty.js +0 -12
  250. package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/multi-schema.js +0 -124
  251. package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/single-schema-inventory.js +0 -64
  252. package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/two-tables.js +0 -66
  253. package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/migrate-stubs/connection-error.js +0 -9
  254. package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/migrate-stubs/partial.js +0 -29
  255. package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/migrate-stubs/rollback.js +0 -26
  256. package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/migrate-stubs/success.js +0 -43
  257. package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/multi-schema/audit/events.js +0 -18
  258. package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/multi-schema/inventory/products.js +0 -9
  259. package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/multi-schema/users.js +0 -8
  260. package/generators/tests/unit/lib/dbschema-kit/connection.test.js +0 -112
  261. package/generators/tests/unit/lib/dbschema-kit/ddl-generator.test.js +0 -205
  262. package/generators/tests/unit/lib/dbschema-kit/define-model.test.js +0 -56
  263. package/generators/tests/unit/lib/dbschema-kit/dialect/index.test.js +0 -46
  264. package/generators/tests/unit/lib/dbschema-kit/dialect/mysql.test.js +0 -126
  265. package/generators/tests/unit/lib/dbschema-kit/dialect/oracle.test.js +0 -126
  266. package/generators/tests/unit/lib/dbschema-kit/dialect/postgres.test.js +0 -131
  267. package/generators/tests/unit/lib/dbschema-kit/dialect/sqlite.test.js +0 -126
  268. package/generators/tests/unit/lib/dbschema-kit/driver-loader.test.js +0 -93
  269. package/generators/tests/unit/lib/dbschema-kit/emitters/create-index.test.js +0 -173
  270. package/generators/tests/unit/lib/dbschema-kit/emitters/create-table.test.js +0 -376
  271. package/generators/tests/unit/lib/dbschema-kit/emitters/drop-table.test.js +0 -78
  272. package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/invalid-dialect.env +0 -6
  273. package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/missing-dialect.env +0 -5
  274. package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/missing-host.env +0 -5
  275. package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/oracle-valid.env +0 -6
  276. package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/postgres-valid.env +0 -7
  277. package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/sqlite-valid.env +0 -2
  278. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/category.js +0 -11
  279. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/item_product.js +0 -11
  280. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/stock_inbound.js +0 -24
  281. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/stock_inbound_item.js +0 -28
  282. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/supplier.js +0 -9
  283. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/warehouse.js +0 -9
  284. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-invalid/orphan.js +0 -17
  285. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/master/category.js +0 -11
  286. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/master/item_product.js +0 -11
  287. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/master/supplier.js +0 -9
  288. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/master/warehouse.js +0 -9
  289. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/transactions/stock_inbound.js +0 -24
  290. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/transactions/stock_inbound_item.js +0 -28
  291. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/multi-schema/audit/events.js +0 -18
  292. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/multi-schema/inventory/products.js +0 -9
  293. package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/multi-schema/public/users.js +0 -9
  294. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/duplicate-subfolder/extra/category.js +0 -8
  295. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/duplicate-subfolder/master/category.js +0 -8
  296. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/duplicate-tablename/bar.js +0 -8
  297. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/duplicate-tablename/foo.js +0 -8
  298. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/empty-folder/README.md +0 -1
  299. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/invalid-export/plain.js +0 -3
  300. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/invalid-schema/bad.js +0 -6
  301. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/legacy-pattern/legacy.js +0 -12
  302. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/multi-schema-distinct/audit/products.js +0 -9
  303. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/multi-schema-distinct/inventory/products.js +0 -9
  304. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/multi-schema-duplicate/a/products.js +0 -8
  305. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/multi-schema-duplicate/b/products.js +0 -8
  306. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/nested-deep/a/b/c/deep_table.js +0 -8
  307. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/.hidden/ignored.js +0 -7
  308. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/master/category.js +0 -8
  309. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/master/supplier.js +0 -8
  310. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/transactions/stock_inbound.js +0 -8
  311. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/transactions/stock_inbound_item.js +0 -8
  312. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/valid-multiple/category.js +0 -8
  313. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/valid-multiple/item_product.js +0 -9
  314. package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/valid-single/category.js +0 -8
  315. package/generators/tests/unit/lib/dbschema-kit/integration.test.js +0 -217
  316. package/generators/tests/unit/lib/dbschema-kit/introspect-mapper.test.js +0 -403
  317. package/generators/tests/unit/lib/dbschema-kit/ir-builder.test.js +0 -390
  318. package/generators/tests/unit/lib/dbschema-kit/loader.test.js +0 -128
  319. package/generators/tests/unit/lib/dbschema-kit/naming.test.js +0 -170
  320. package/generators/tests/unit/lib/dbschema-kit/parser/shorthand-parser.test.js +0 -237
  321. package/generators/tests/unit/lib/dbschema-kit/schema-printer.test.js +0 -251
  322. package/generators/tests/unit/lib/dbschema-kit/statement-modifier.test.js +0 -105
  323. package/generators/tests/unit/lib/dbschema-kit/statement-splitter.test.js +0 -165
  324. package/generators/tests/unit/lib/dbschema-kit/topological-sort.test.js +0 -135
  325. package/generators/tests/unit/lib/dbschema-kit/validator/check-compatibility-validator.test.js +0 -373
  326. package/generators/tests/unit/lib/dbschema-kit/validator/circular-relation-validator.test.js +0 -454
  327. package/generators/tests/unit/lib/dbschema-kit/validator/cross-model-validator.test.js +0 -512
  328. package/generators/tests/unit/lib/dbschema-kit/validator/enhanced-validate-integration.test.js +0 -390
  329. package/generators/tests/unit/lib/dbschema-kit/validator/naming-convention-validator.test.js +0 -306
  330. package/generators/tests/unit/lib/dbschema-kit/validator/schema-validator.test.js +0 -443
  331. package/generators/tests/unit/lib/dbschema-kit/validator/type-compatibility-validator.test.js +0 -440
  332. package/generators/tests/unit/lib/dbschema-kit/validator/validator-reporter.test.js +0 -172
  333. package/generators/tests/unit/lib/metadata-manager-dashboard.test.js +0 -256
  334. package/generators/tests/unit/lib/payload-validator-fieldpolicy.test.js +0 -240
  335. package/generators/tests/unit/lib/processor-validation-generator.test.js +0 -300
  336. package/generators/tests/unit/lib/sensitive-field-masker.test.js +0 -170
  337. package/generators/tests/unit/lib/sql-table-extractor.test.js +0 -119
  338. package/scripts/generate-integrity-manifest.js +0 -124
  339. package/scripts/snapshot-cli-contracts.js +0 -194
  340. package/scripts/verify-publish.js +0 -56
@@ -0,0 +1,582 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Apply Engine — translate delta dari diff-engine menjadi `ALTER TABLE`
5
+ * statement incremental. Komplemen `ddl-generator.js` yang menghasilkan full
6
+ * CREATE TABLE.
7
+ *
8
+ * Operasi yang di-handle (MVP):
9
+ * - ADD COLUMN (additive, default)
10
+ * - DROP COLUMN (destruktif, butuh allowDrop)
11
+ * - MODIFY COLUMN (length / nullable, butuh allowModify)
12
+ * - CREATE INDEX (additive)
13
+ * - DROP INDEX (destruktif, butuh allowDrop)
14
+ * - ADD CONSTRAINT UNIQUE (additive)
15
+ * - DROP CONSTRAINT UNIQUE (destruktif, butuh allowDrop)
16
+ *
17
+ * Operasi yang TIDAK di-handle (deferred):
18
+ * - ALTER COLUMN type change (butuh data conversion strategy per dialect)
19
+ * - PK changes (butuh rebuild table)
20
+ * - FK changes (butuh cross-model validation + dialect syntax kompleks)
21
+ * - DEFAULT value changes (defer ke fase berikutnya)
22
+ * - CHECK constraint changes
23
+ *
24
+ * SQLite tidak mendukung ALTER COLUMN / DROP COLUMN tanpa rebuild table.
25
+ * Untuk dialect ini, MODIFY dan DROP COLUMN otomatis di-skip dengan reason
26
+ * 'sqlite limitation' walaupun flag opt-in aktif.
27
+ *
28
+ * Output dipesan dengan urutan aman untuk dependency:
29
+ * 1. ADD COLUMN (no dependencies)
30
+ * 2. CREATE INDEX (depend on column existence)
31
+ * 3. ADD CONSTRAINT UNIQUE (depend on column existence)
32
+ * 4. ALTER/MODIFY COLUMN (modify after additive done)
33
+ * 5. DROP CONSTRAINT (before drop column to avoid dependency error)
34
+ * 6. DROP INDEX (before drop column)
35
+ * 7. DROP COLUMN (last)
36
+ *
37
+ * @module lib/dbschema-kit/apply-engine
38
+ */
39
+
40
+ const { getDialect } = require('./dialect');
41
+ const {
42
+ emitAddColumn,
43
+ emitDropColumn,
44
+ emitModifyColumn,
45
+ emitCreateIndex,
46
+ emitDropIndex,
47
+ emitAddUnique,
48
+ emitDropUnique
49
+ } = require('./emitters/alter-table');
50
+
51
+ const VALID_DIALECTS = ['postgres', 'mysql', 'oracle', 'sqlite'];
52
+
53
+ // Kategori reason dari diff-engine compareFieldDetails. Reason berbentuk string
54
+ // dengan prefix "type:", "length:", "precision:", "scale:", "nullable:",
55
+ // "default:", "default kind:", atau "default (weak):". Kategorisasi ini
56
+ // menentukan apakah modify aman di-emit (length/nullable) atau di-skip
57
+ // (type/default — deferred).
58
+ function classifyMismatchReasons(reasons) {
59
+ const result = {
60
+ hasType: false,
61
+ hasLength: false,
62
+ hasPrecision: false,
63
+ hasScale: false,
64
+ hasNullable: false,
65
+ hasDefault: false
66
+ };
67
+ if (!Array.isArray(reasons)) return result;
68
+ for (const r of reasons) {
69
+ if (typeof r !== 'string') continue;
70
+ if (r.startsWith('type:')) result.hasType = true;
71
+ else if (r.startsWith('length:')) result.hasLength = true;
72
+ else if (r.startsWith('precision:')) result.hasPrecision = true;
73
+ else if (r.startsWith('scale:')) result.hasScale = true;
74
+ else if (r.startsWith('nullable:')) result.hasNullable = true;
75
+ else if (r.startsWith('default')) result.hasDefault = true;
76
+ }
77
+ return result;
78
+ }
79
+
80
+ // Resolve IR field definition dari delta summary. Delta engine menyimpan
81
+ // summary terbatas (name, type, length, precision, scale, nullable). Untuk
82
+ // emitter kita perlu shape kompatibel dengan dialect.mapType + notnull flag.
83
+ function buildFieldFromSummary(summary) {
84
+ const field = {};
85
+ if (summary.type !== undefined) field.type = summary.type;
86
+ if (summary.length !== undefined) field.length = summary.length;
87
+ if (summary.precision !== undefined) field.precision = summary.precision;
88
+ if (summary.scale !== undefined) field.scale = summary.scale;
89
+ if (summary.nullable === false) field.notnull = true;
90
+ return field;
91
+ }
92
+
93
+ // Resolve field IR dari SDF map bila tersedia (untuk default value dan
94
+ // notnull yang akurat). Bila tidak ditemukan, fallback ke summary.
95
+ function resolveFieldIR(sdfModels, tableName, fieldName, fallbackSummary) {
96
+ if (sdfModels) {
97
+ const ir = lookupSdfIR(sdfModels, tableName);
98
+ if (ir && ir.fields && ir.fields[fieldName]) {
99
+ return ir.fields[fieldName];
100
+ }
101
+ }
102
+ return buildFieldFromSummary(fallbackSummary);
103
+ }
104
+
105
+ function lookupSdfIR(sdfModels, tableName) {
106
+ if (!sdfModels) return null;
107
+ if (sdfModels instanceof Map) {
108
+ for (const ir of sdfModels.values()) {
109
+ if (ir && ir.tableName === tableName) return ir;
110
+ }
111
+ return null;
112
+ }
113
+ if (Array.isArray(sdfModels)) {
114
+ for (const ir of sdfModels) {
115
+ if (ir && ir.tableName === tableName) return ir;
116
+ }
117
+ return null;
118
+ }
119
+ if (typeof sdfModels === 'object') {
120
+ for (const key of Object.keys(sdfModels)) {
121
+ const ir = sdfModels[key];
122
+ if (ir && ir.tableName === tableName) return ir;
123
+ }
124
+ }
125
+ return null;
126
+ }
127
+
128
+ function resolveTableIR(sdfModels, delta) {
129
+ const fromSdf = lookupSdfIR(sdfModels, delta.tableName);
130
+ if (fromSdf) {
131
+ return { tableName: fromSdf.tableName, schemaName: fromSdf.schemaName || null };
132
+ }
133
+ return { tableName: delta.tableName, schemaName: null };
134
+ }
135
+
136
+ // ─────────────────────────────────────────────────────────────
137
+ // Statement bucketing per kategori (untuk ordering aman)
138
+ // ─────────────────────────────────────────────────────────────
139
+
140
+ function buildBuckets() {
141
+ return {
142
+ addColumns: [],
143
+ createIndexes: [],
144
+ addUniques: [],
145
+ modifyColumns: [],
146
+ dropConstraints: [],
147
+ dropIndexes: [],
148
+ dropColumns: []
149
+ };
150
+ }
151
+
152
+ function flattenBuckets(buckets) {
153
+ return [
154
+ ...buckets.addColumns,
155
+ ...buckets.createIndexes,
156
+ ...buckets.addUniques,
157
+ ...buckets.modifyColumns,
158
+ ...buckets.dropConstraints,
159
+ ...buckets.dropIndexes,
160
+ ...buckets.dropColumns
161
+ ];
162
+ }
163
+
164
+ // ─────────────────────────────────────────────────────────────
165
+ // Per-delta processing
166
+ // ─────────────────────────────────────────────────────────────
167
+
168
+ function processFieldsOnlyInSdf(delta, tableIR, dialect, buckets, skipped, sdfModels, summary) {
169
+ const list = delta.fields && Array.isArray(delta.fields.onlyInSdf) ? delta.fields.onlyInSdf : [];
170
+ for (const fSummary of list) {
171
+ const fieldIR = resolveFieldIR(sdfModels, delta.tableName, fSummary.name, fSummary);
172
+ try {
173
+ buckets.addColumns.push(emitAddColumn(tableIR, fSummary.name, fieldIR, dialect));
174
+ summary.totalAdditions++;
175
+ } catch (err) {
176
+ skipped.push({
177
+ table: delta.tableName,
178
+ kind: 'add-column',
179
+ target: fSummary.name,
180
+ reason: 'emit-error',
181
+ description: err && err.message ? err.message : String(err)
182
+ });
183
+ }
184
+ }
185
+ }
186
+
187
+ function processFieldsOnlyInDb(delta, tableIR, dialect, options, buckets, skipped, summary) {
188
+ const list = delta.fields && Array.isArray(delta.fields.onlyInDb) ? delta.fields.onlyInDb : [];
189
+ for (const fSummary of list) {
190
+ if (!options.allowDrop) {
191
+ skipped.push({
192
+ table: delta.tableName,
193
+ kind: 'drop-column',
194
+ target: fSummary.name,
195
+ reason: 'requires --allow-drop',
196
+ description: `${delta.tableName}.${fSummary.name} exists in DB but not in SDF`
197
+ });
198
+ continue;
199
+ }
200
+ if (dialect.name === 'sqlite') {
201
+ skipped.push({
202
+ table: delta.tableName,
203
+ kind: 'drop-column',
204
+ target: fSummary.name,
205
+ reason: 'sqlite limitation',
206
+ description: `SQLite does not support DROP COLUMN without table rebuild (${delta.tableName}.${fSummary.name})`
207
+ });
208
+ continue;
209
+ }
210
+ try {
211
+ buckets.dropColumns.push(emitDropColumn(tableIR, fSummary.name, dialect));
212
+ summary.totalDeletions++;
213
+ } catch (err) {
214
+ skipped.push({
215
+ table: delta.tableName,
216
+ kind: 'drop-column',
217
+ target: fSummary.name,
218
+ reason: 'emit-error',
219
+ description: err && err.message ? err.message : String(err)
220
+ });
221
+ }
222
+ }
223
+ }
224
+
225
+ function processFieldsMismatched(delta, tableIR, dialect, options, buckets, skipped, sdfModels, summary) {
226
+ const list = delta.fields && Array.isArray(delta.fields.mismatched) ? delta.fields.mismatched : [];
227
+ for (const m of list) {
228
+ const cls = classifyMismatchReasons(m.reasons);
229
+
230
+ // Type change: defer (butuh data conversion strategy)
231
+ if (cls.hasType) {
232
+ skipped.push({
233
+ table: delta.tableName,
234
+ kind: 'modify-type',
235
+ target: m.name,
236
+ reason: 'deferred',
237
+ description: `Type change for ${delta.tableName}.${m.name} requires explicit data conversion strategy (deferred from MVP)`
238
+ });
239
+ continue;
240
+ }
241
+ // Default change: defer
242
+ if (cls.hasDefault) {
243
+ skipped.push({
244
+ table: delta.tableName,
245
+ kind: 'modify-default',
246
+ target: m.name,
247
+ reason: 'deferred',
248
+ description: `Default value change for ${delta.tableName}.${m.name} deferred from MVP`
249
+ });
250
+ continue;
251
+ }
252
+ // Precision / scale: defer (mirip type change)
253
+ if (cls.hasPrecision || cls.hasScale) {
254
+ skipped.push({
255
+ table: delta.tableName,
256
+ kind: 'modify-precision',
257
+ target: m.name,
258
+ reason: 'deferred',
259
+ description: `Precision/scale change for ${delta.tableName}.${m.name} deferred from MVP`
260
+ });
261
+ continue;
262
+ }
263
+
264
+ const changeNullable = cls.hasNullable;
265
+ const changeLength = cls.hasLength;
266
+ if (!changeNullable && !changeLength) {
267
+ // Nothing actionable
268
+ continue;
269
+ }
270
+
271
+ if (!options.allowModify) {
272
+ const detailParts = [];
273
+ if (changeLength) detailParts.push('length');
274
+ if (changeNullable) detailParts.push('nullable');
275
+ skipped.push({
276
+ table: delta.tableName,
277
+ kind: 'modify-column',
278
+ target: m.name,
279
+ reason: 'requires --allow-modify',
280
+ description: `${delta.tableName}.${m.name} ${detailParts.join('/')} drift requires --allow-modify`
281
+ });
282
+ continue;
283
+ }
284
+
285
+ if (dialect.name === 'sqlite') {
286
+ skipped.push({
287
+ table: delta.tableName,
288
+ kind: 'modify-column',
289
+ target: m.name,
290
+ reason: 'sqlite limitation',
291
+ description: `SQLite does not support ALTER COLUMN without table rebuild (${delta.tableName}.${m.name})`
292
+ });
293
+ continue;
294
+ }
295
+
296
+ const fieldIR = resolveFieldIR(sdfModels, delta.tableName, m.name, m.sdf);
297
+ try {
298
+ const statements = emitModifyColumn(tableIR, m.name, fieldIR, { changeNullable, changeLength }, dialect);
299
+ for (const s of statements) {
300
+ buckets.modifyColumns.push(s);
301
+ summary.totalModifications++;
302
+ }
303
+ } catch (err) {
304
+ skipped.push({
305
+ table: delta.tableName,
306
+ kind: 'modify-column',
307
+ target: m.name,
308
+ reason: 'emit-error',
309
+ description: err && err.message ? err.message : String(err)
310
+ });
311
+ }
312
+ }
313
+ }
314
+
315
+ function processIndexes(delta, tableIR, dialect, options, buckets, skipped, summary) {
316
+ if (!delta.indexes) return;
317
+
318
+ const addList = Array.isArray(delta.indexes.onlyInSdf) ? delta.indexes.onlyInSdf : [];
319
+ for (const idx of addList) {
320
+ const cols = Array.isArray(idx.columns) ? idx.columns : [];
321
+ if (cols.length === 0) continue;
322
+ try {
323
+ buckets.createIndexes.push(emitCreateIndex(tableIR, cols, dialect));
324
+ summary.totalAdditions++;
325
+ } catch (err) {
326
+ skipped.push({
327
+ table: delta.tableName,
328
+ kind: 'create-index',
329
+ target: cols.join(','),
330
+ reason: 'emit-error',
331
+ description: err && err.message ? err.message : String(err)
332
+ });
333
+ }
334
+ }
335
+
336
+ const dropList = Array.isArray(delta.indexes.onlyInDb) ? delta.indexes.onlyInDb : [];
337
+ for (const idx of dropList) {
338
+ const cols = Array.isArray(idx.columns) ? idx.columns : [];
339
+ if (cols.length === 0) continue;
340
+ if (!options.allowDrop) {
341
+ skipped.push({
342
+ table: delta.tableName,
343
+ kind: 'drop-index',
344
+ target: cols.join(','),
345
+ reason: 'requires --allow-drop',
346
+ description: `Index on ${delta.tableName}(${cols.join(', ')}) exists in DB but not in SDF`
347
+ });
348
+ continue;
349
+ }
350
+ try {
351
+ buckets.dropIndexes.push(emitDropIndex(tableIR, cols, dialect, { name: idx.name }));
352
+ summary.totalDeletions++;
353
+ } catch (err) {
354
+ skipped.push({
355
+ table: delta.tableName,
356
+ kind: 'drop-index',
357
+ target: cols.join(','),
358
+ reason: 'emit-error',
359
+ description: err && err.message ? err.message : String(err)
360
+ });
361
+ }
362
+ }
363
+ }
364
+
365
+ function processUniques(delta, tableIR, dialect, options, buckets, skipped, summary) {
366
+ if (!delta.uniques) return;
367
+
368
+ const addList = Array.isArray(delta.uniques.onlyInSdf) ? delta.uniques.onlyInSdf : [];
369
+ for (const uq of addList) {
370
+ const cols = Array.isArray(uq.columns) ? uq.columns : [];
371
+ if (cols.length === 0) continue;
372
+ try {
373
+ buckets.addUniques.push(emitAddUnique(tableIR, cols, dialect));
374
+ summary.totalAdditions++;
375
+ } catch (err) {
376
+ skipped.push({
377
+ table: delta.tableName,
378
+ kind: 'add-unique',
379
+ target: cols.join(','),
380
+ reason: 'emit-error',
381
+ description: err && err.message ? err.message : String(err)
382
+ });
383
+ }
384
+ }
385
+
386
+ const dropList = Array.isArray(delta.uniques.onlyInDb) ? delta.uniques.onlyInDb : [];
387
+ for (const uq of dropList) {
388
+ const cols = Array.isArray(uq.columns) ? uq.columns : [];
389
+ if (cols.length === 0) continue;
390
+ if (!options.allowDrop) {
391
+ skipped.push({
392
+ table: delta.tableName,
393
+ kind: 'drop-unique',
394
+ target: cols.join(','),
395
+ reason: 'requires --allow-drop',
396
+ description: `Unique on ${delta.tableName}(${cols.join(', ')}) exists in DB but not in SDF`
397
+ });
398
+ continue;
399
+ }
400
+ try {
401
+ buckets.dropConstraints.push(emitDropUnique(tableIR, cols, dialect, { name: uq.name }));
402
+ summary.totalDeletions++;
403
+ } catch (err) {
404
+ skipped.push({
405
+ table: delta.tableName,
406
+ kind: 'drop-unique',
407
+ target: cols.join(','),
408
+ reason: 'emit-error',
409
+ description: err && err.message ? err.message : String(err)
410
+ });
411
+ }
412
+ }
413
+ }
414
+
415
+ function noteDeferredSections(delta, skipped) {
416
+ // PK changes — deferred dari MVP karena butuh rebuild table.
417
+ if (delta.primaryKey && delta.primaryKey.match === false) {
418
+ const sdf = Array.isArray(delta.primaryKey.sdf) ? delta.primaryKey.sdf : [];
419
+ const db = Array.isArray(delta.primaryKey.db) ? delta.primaryKey.db : [];
420
+ skipped.push({
421
+ table: delta.tableName,
422
+ kind: 'primary-key',
423
+ target: `pk(${sdf.join(',') || '∅'} vs ${db.join(',') || '∅'})`,
424
+ reason: 'deferred',
425
+ description: `Primary key changes for ${delta.tableName} deferred from MVP (requires table rebuild)`
426
+ });
427
+ }
428
+
429
+ if (delta.foreignKeys) {
430
+ const fkOnlySdf = Array.isArray(delta.foreignKeys.onlyInSdf) ? delta.foreignKeys.onlyInSdf : [];
431
+ const fkOnlyDb = Array.isArray(delta.foreignKeys.onlyInDb) ? delta.foreignKeys.onlyInDb : [];
432
+ const fkMismatch = Array.isArray(delta.foreignKeys.mismatched) ? delta.foreignKeys.mismatched : [];
433
+ for (const fk of fkOnlySdf) {
434
+ skipped.push({
435
+ table: delta.tableName,
436
+ kind: 'foreign-key',
437
+ target: `${fk.localKey} -> ${fk.target}.${fk.references}`,
438
+ reason: 'deferred',
439
+ description: `Foreign key changes deferred from MVP (additive ${delta.tableName}.${fk.localKey})`
440
+ });
441
+ }
442
+ for (const fk of fkOnlyDb) {
443
+ skipped.push({
444
+ table: delta.tableName,
445
+ kind: 'foreign-key',
446
+ target: `${fk.localKey} -> ${fk.target}.${fk.references}`,
447
+ reason: 'deferred',
448
+ description: `Foreign key changes deferred from MVP (drop ${delta.tableName}.${fk.localKey})`
449
+ });
450
+ }
451
+ for (const fk of fkMismatch) {
452
+ skipped.push({
453
+ table: delta.tableName,
454
+ kind: 'foreign-key',
455
+ target: `${fk.localKey} -> ${fk.target}.${fk.references}`,
456
+ reason: 'deferred',
457
+ description: `Foreign key action change deferred from MVP (${delta.tableName}.${fk.localKey})`
458
+ });
459
+ }
460
+ }
461
+
462
+ if (delta.checks) {
463
+ const cOnlySdf = Array.isArray(delta.checks.onlyInSdf) ? delta.checks.onlyInSdf : [];
464
+ const cOnlyDb = Array.isArray(delta.checks.onlyInDb) ? delta.checks.onlyInDb : [];
465
+ for (const c of cOnlySdf) {
466
+ skipped.push({
467
+ table: delta.tableName,
468
+ kind: 'check-constraint',
469
+ target: c.field || c.expression || '(check)',
470
+ reason: 'deferred',
471
+ description: `Check constraint changes deferred from MVP (additive ${delta.tableName})`
472
+ });
473
+ }
474
+ for (const c of cOnlyDb) {
475
+ skipped.push({
476
+ table: delta.tableName,
477
+ kind: 'check-constraint',
478
+ target: c.field || c.expression || '(check)',
479
+ reason: 'deferred',
480
+ description: `Check constraint changes deferred from MVP (drop ${delta.tableName})`
481
+ });
482
+ }
483
+ }
484
+ }
485
+
486
+ // ─────────────────────────────────────────────────────────────
487
+ // Public API
488
+ // ─────────────────────────────────────────────────────────────
489
+
490
+ /**
491
+ * Generate ALTER statement dari delta diff-engine per model.
492
+ *
493
+ * @param {Array<Object>} deltas - Output dari diffModels()
494
+ * @param {Object} options
495
+ * @param {string} options.dialect - 'postgres' | 'mysql' | 'oracle' | 'sqlite'
496
+ * @param {boolean} [options.allowDrop=false]
497
+ * @param {boolean} [options.allowModify=false]
498
+ * @param {Map|Object|Array} [options.sdfModels] - SDF model map untuk resolve field IR penuh
499
+ * @returns {{
500
+ * statements: Array<{ table: string, sql: string }>,
501
+ * statementsByTable: Object<string, string[]>,
502
+ * skipped: Array<{ table, kind, target, reason, description }>,
503
+ * summary: { totalAdditions, totalModifications, totalDeletions, totalSkipped, tablesAffected }
504
+ * }}
505
+ */
506
+ function generateAlterStatements(deltas, options) {
507
+ if (!Array.isArray(deltas)) {
508
+ throw new Error('generateAlterStatements: deltas must be an array');
509
+ }
510
+ if (!options || typeof options !== 'object') {
511
+ throw new Error('generateAlterStatements: options object is required');
512
+ }
513
+ if (!VALID_DIALECTS.includes(options.dialect)) {
514
+ throw new Error(
515
+ `generateAlterStatements: invalid dialect '${options.dialect}'. ` +
516
+ `Supported: ${VALID_DIALECTS.join(', ')}`
517
+ );
518
+ }
519
+
520
+ const allowDrop = options.allowDrop === true;
521
+ const allowModify = options.allowModify === true;
522
+ const sdfModels = options.sdfModels || null;
523
+ const dialect = getDialect(options.dialect);
524
+
525
+ const statements = [];
526
+ const statementsByTable = {};
527
+ const skipped = [];
528
+ const summary = {
529
+ totalAdditions: 0,
530
+ totalModifications: 0,
531
+ totalDeletions: 0,
532
+ totalSkipped: 0,
533
+ tablesAffected: 0
534
+ };
535
+
536
+ const tablesWithStatements = new Set();
537
+ const localOptions = { allowDrop, allowModify };
538
+
539
+ for (const delta of deltas) {
540
+ if (!delta || typeof delta.tableName !== 'string') continue;
541
+ if (!delta.hasDrift) continue;
542
+
543
+ const tableIR = resolveTableIR(sdfModels, delta);
544
+ const buckets = buildBuckets();
545
+
546
+ processFieldsOnlyInSdf(delta, tableIR, dialect, buckets, skipped, sdfModels, summary);
547
+ processFieldsOnlyInDb(delta, tableIR, dialect, localOptions, buckets, skipped, summary);
548
+ processFieldsMismatched(delta, tableIR, dialect, localOptions, buckets, skipped, sdfModels, summary);
549
+ processIndexes(delta, tableIR, dialect, localOptions, buckets, skipped, summary);
550
+ processUniques(delta, tableIR, dialect, localOptions, buckets, skipped, summary);
551
+ noteDeferredSections(delta, skipped);
552
+
553
+ const flat = flattenBuckets(buckets);
554
+ if (flat.length > 0) {
555
+ tablesWithStatements.add(delta.tableName);
556
+ statementsByTable[delta.tableName] = flat.slice();
557
+ for (const sql of flat) {
558
+ statements.push({ table: delta.tableName, sql });
559
+ }
560
+ }
561
+ }
562
+
563
+ summary.totalSkipped = skipped.length;
564
+ summary.tablesAffected = tablesWithStatements.size;
565
+
566
+ return {
567
+ statements,
568
+ statementsByTable,
569
+ skipped,
570
+ summary
571
+ };
572
+ }
573
+
574
+ module.exports = {
575
+ generateAlterStatements,
576
+ _internal: {
577
+ classifyMismatchReasons,
578
+ buildFieldFromSummary,
579
+ resolveTableIR,
580
+ lookupSdfIR
581
+ }
582
+ };