@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
@@ -1,393 +0,0 @@
1
- 'use strict';
2
-
3
- const test = require('node:test');
4
- const assert = require('node:assert');
5
- const path = require('node:path');
6
- const fs = require('node:fs');
7
- const os = require('node:os');
8
- const { spawnSync } = require('node:child_process');
9
-
10
- const REPO_ROOT = path.resolve(__dirname, '..', '..', '..', '..', '..');
11
- const CLI_SCRIPT = path.join(REPO_ROOT, 'cli', 'dbschema-introspect.js');
12
-
13
- const CONFIG_PG = path.resolve(__dirname, '..', 'fixtures', 'connection', 'postgres-valid.env');
14
-
15
- const STUB_DIR = path.resolve(__dirname, 'fixtures', 'introspect-stubs');
16
- const STUB_TWO = path.join(STUB_DIR, 'two-tables.js');
17
- const STUB_EMPTY = path.join(STUB_DIR, 'empty.js');
18
- const STUB_CONN = path.join(STUB_DIR, 'connection-error.js');
19
- const STUB_MULTI = path.join(STUB_DIR, 'multi-schema.js');
20
- const STUB_INVENTORY = path.join(STUB_DIR, 'single-schema-inventory.js');
21
- const STUB_ALL_SCHEMAS = path.join(STUB_DIR, 'all-schemas-listing.js');
22
-
23
- function runIntrospect(args, options = {}) {
24
- return spawnSync(process.execPath, [CLI_SCRIPT, ...args], {
25
- encoding: 'utf-8',
26
- env: { ...process.env, NO_COLOR: '1', ...(options.env || {}) },
27
- ...options
28
- });
29
- }
30
-
31
- function withTmpDir(fn) {
32
- const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'dbsk-introspect-'));
33
- try {
34
- return fn(tmpRoot);
35
- } finally {
36
- fs.rmSync(tmpRoot, { recursive: true, force: true });
37
- }
38
- }
39
-
40
- test('introspect: --help → exit 0, stdout berisi usage', () => {
41
- const result = runIntrospect(['--help']);
42
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
43
- assert.match(result.stdout, /dbschema Introspect/);
44
- assert.match(result.stdout, /--config=<file>/);
45
- assert.match(result.stdout, /--output=<path>/);
46
- assert.match(result.stdout, /--table=<name>/);
47
- });
48
-
49
- test('introspect: tanpa --config → exit 1, stderr "config" required', () => {
50
- const result = runIntrospect(['--output=./schema']);
51
- assert.strictEqual(result.status, 1);
52
- assert.match(result.stderr, /--config=<file> is required/);
53
- });
54
-
55
- test('introspect: --config menunjuk file yang tidak ada → exit 1, stderr "Config file not found"', () => {
56
- const result = runIntrospect(['--config=does-not-exist.env', '--output=./schema']);
57
- assert.strictEqual(result.status, 1);
58
- assert.match(result.stderr, /Config file not found/);
59
- });
60
-
61
- test('introspect: tanpa --output dan tanpa --dry-run → exit 1, stderr "output" required', () => {
62
- const result = runIntrospect([`--config=${CONFIG_PG}`]);
63
- assert.strictEqual(result.status, 1);
64
- assert.match(result.stderr, /--output=<path> is required/);
65
- });
66
-
67
- test('introspect: bulk mode tulis ke folder, semua tabel jadi file .js', () => {
68
- withTmpDir((tmpRoot) => {
69
- const outDir = path.join(tmpRoot, 'schema');
70
- const result = runIntrospect(
71
- [`--config=${CONFIG_PG}`, `--output=${outDir}`],
72
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_TWO } }
73
- );
74
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
75
- assert.ok(fs.existsSync(path.join(outDir, 'category.js')));
76
- assert.ok(fs.existsSync(path.join(outDir, 'item_product.js')));
77
- const content = fs.readFileSync(path.join(outDir, 'category.js'), 'utf8');
78
- assert.match(content, /defineModel\('category'/);
79
- });
80
- });
81
-
82
- test('introspect: single mode --output=folder + --table → file di <folder>/<table>.js', () => {
83
- withTmpDir((tmpRoot) => {
84
- const outDir = path.join(tmpRoot, 'schema');
85
- const result = runIntrospect(
86
- [`--config=${CONFIG_PG}`, `--output=${outDir}`, '--table=category'],
87
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_TWO } }
88
- );
89
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
90
- assert.ok(fs.existsSync(path.join(outDir, 'category.js')));
91
- // Should NOT emit other table.
92
- assert.ok(!fs.existsSync(path.join(outDir, 'item_product.js')));
93
- });
94
- });
95
-
96
- test('introspect: single mode --output=file.js + --table=foo (basename match) → tulis ke file', () => {
97
- withTmpDir((tmpRoot) => {
98
- const outFile = path.join(tmpRoot, 'category.js');
99
- const result = runIntrospect(
100
- [`--config=${CONFIG_PG}`, `--output=${outFile}`, '--table=category'],
101
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_TWO } }
102
- );
103
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
104
- assert.ok(fs.existsSync(outFile));
105
- const content = fs.readFileSync(outFile, 'utf8');
106
- assert.match(content, /defineModel\('category'/);
107
- });
108
- });
109
-
110
- test('introspect: single mode --output=file.js basename mismatch dengan --table → exit 1', () => {
111
- withTmpDir((tmpRoot) => {
112
- const outFile = path.join(tmpRoot, 'wrong-name.js');
113
- const result = runIntrospect(
114
- [`--config=${CONFIG_PG}`, `--output=${outFile}`, '--table=category'],
115
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_TWO } }
116
- );
117
- assert.strictEqual(result.status, 1);
118
- assert.match(result.stderr, /does not match --table/);
119
- });
120
- });
121
-
122
- test('introspect: bulk mode --output adalah file .js (tanpa --table) → exit 1', () => {
123
- withTmpDir((tmpRoot) => {
124
- const outFile = path.join(tmpRoot, 'all.js');
125
- const result = runIntrospect(
126
- [`--config=${CONFIG_PG}`, `--output=${outFile}`],
127
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_TWO } }
128
- );
129
- assert.strictEqual(result.status, 1);
130
- assert.match(result.stderr, /Bulk mode requires a folder/);
131
- });
132
- });
133
-
134
- test('introspect: file existing tanpa --force → exit 1, stderr "File already exists"', () => {
135
- withTmpDir((tmpRoot) => {
136
- const outDir = path.join(tmpRoot, 'schema');
137
- fs.mkdirSync(outDir, { recursive: true });
138
- fs.writeFileSync(path.join(outDir, 'category.js'), '// pre-existing');
139
- const result = runIntrospect(
140
- [`--config=${CONFIG_PG}`, `--output=${outDir}`, '--table=category'],
141
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_TWO } }
142
- );
143
- assert.strictEqual(result.status, 1);
144
- assert.match(result.stderr, /File already exists/);
145
- });
146
- });
147
-
148
- test('introspect: file existing dengan --force → overwrite sukses', () => {
149
- withTmpDir((tmpRoot) => {
150
- const outDir = path.join(tmpRoot, 'schema');
151
- fs.mkdirSync(outDir, { recursive: true });
152
- const target = path.join(outDir, 'category.js');
153
- fs.writeFileSync(target, '// pre-existing');
154
- const result = runIntrospect(
155
- [`--config=${CONFIG_PG}`, `--output=${outDir}`, '--table=category', '--force'],
156
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_TWO } }
157
- );
158
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
159
- const content = fs.readFileSync(target, 'utf8');
160
- assert.match(content, /defineModel\('category'/);
161
- assert.doesNotMatch(content, /pre-existing/);
162
- });
163
- });
164
-
165
- test('introspect: --dry-run tanpa --output → exit 2, stdout berisi factory function', () => {
166
- const result = runIntrospect(
167
- [`--config=${CONFIG_PG}`, '--dry-run'],
168
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_TWO } }
169
- );
170
- assert.strictEqual(result.status, 2, `expected exit 2, got ${result.status}. stderr: ${result.stderr}`);
171
- assert.match(result.stdout, /defineModel\('category'/);
172
- assert.match(result.stdout, /defineModel\('item_product'/);
173
- assert.match(result.stderr, /Dry-run complete/);
174
- });
175
-
176
- test('introspect: --dry-run + --table=foo → exit 2, stdout hanya satu factory function', () => {
177
- const result = runIntrospect(
178
- [`--config=${CONFIG_PG}`, '--dry-run', '--table=category'],
179
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_TWO } }
180
- );
181
- assert.strictEqual(result.status, 2);
182
- assert.match(result.stdout, /defineModel\('category'/);
183
- assert.doesNotMatch(result.stdout, /defineModel\('item_product'/);
184
- });
185
-
186
- test('introspect: connection error → exit 1, stderr "Cannot connect"', () => {
187
- const result = runIntrospect(
188
- [`--config=${CONFIG_PG}`, '--output=./out'],
189
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_CONN } }
190
- );
191
- assert.strictEqual(result.status, 1);
192
- assert.match(result.stderr, /Cannot connect/);
193
- });
194
-
195
- test('introspect: --table tidak ditemukan di DB → exit 1, stderr "not found"', () => {
196
- const result = runIntrospect(
197
- [`--config=${CONFIG_PG}`, '--output=./out', '--table=ghost'],
198
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_EMPTY } }
199
- );
200
- assert.strictEqual(result.status, 1);
201
- assert.match(result.stderr, /'ghost' not found/);
202
- });
203
-
204
- test('introspect: unknown option → exit 1', () => {
205
- const result = runIntrospect(
206
- [`--config=${CONFIG_PG}`, '--output=./out', '--bogus'],
207
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_TWO } }
208
- );
209
- assert.strictEqual(result.status, 1);
210
- assert.match(result.stderr, /Unknown option/);
211
- });
212
-
213
- // =====================================================
214
- // Phase 14: schema-aware CLI flags
215
- // =====================================================
216
-
217
- test('introspect (Phase 14): --schema=inventory bulk → flat layout, semua emit schema: inventory', () => {
218
- withTmpDir((tmpRoot) => {
219
- const outDir = path.join(tmpRoot, 'schema');
220
- const result = runIntrospect(
221
- [`--config=${CONFIG_PG}`, `--output=${outDir}`, '--schema=inventory'],
222
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_INVENTORY } }
223
- );
224
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
225
- // Flat layout (no subfolder per schema for single-schema bulk)
226
- assert.ok(fs.existsSync(path.join(outDir, 'products.js')));
227
- assert.ok(fs.existsSync(path.join(outDir, 'categories.js')));
228
- const productsContent = fs.readFileSync(path.join(outDir, 'products.js'), 'utf8');
229
- assert.match(productsContent, /defineModel\('products'/);
230
- assert.match(productsContent, /schema: 'inventory'/);
231
- });
232
- });
233
-
234
- test('introspect (Phase 14): --schema=inventory,audit bulk → subfolder layout per schema', () => {
235
- withTmpDir((tmpRoot) => {
236
- const outDir = path.join(tmpRoot, 'schema');
237
- const result = runIntrospect(
238
- [`--config=${CONFIG_PG}`, `--output=${outDir}`, '--schema=inventory,audit'],
239
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_MULTI } }
240
- );
241
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
242
- assert.ok(fs.existsSync(path.join(outDir, 'inventory', 'products.js')));
243
- assert.ok(fs.existsSync(path.join(outDir, 'inventory', 'categories.js')));
244
- assert.ok(fs.existsSync(path.join(outDir, 'audit', 'events.js')));
245
- assert.ok(fs.existsSync(path.join(outDir, 'audit', 'logs.js')));
246
- const eventsContent = fs.readFileSync(path.join(outDir, 'audit', 'events.js'), 'utf8');
247
- assert.match(eventsContent, /schema: 'audit'/);
248
- });
249
- });
250
-
251
- test('introspect (Phase 14): --all-schemas → listSchemas() lalu bulk subfolder', () => {
252
- withTmpDir((tmpRoot) => {
253
- const outDir = path.join(tmpRoot, 'schema');
254
- const result = runIntrospect(
255
- [`--config=${CONFIG_PG}`, `--output=${outDir}`, '--all-schemas'],
256
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_ALL_SCHEMAS } }
257
- );
258
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
259
- assert.ok(fs.existsSync(path.join(outDir, 'inventory', 'products.js')));
260
- assert.ok(fs.existsSync(path.join(outDir, 'audit', 'logs.js')));
261
- assert.ok(fs.existsSync(path.join(outDir, 'public', 'users.js')));
262
- });
263
- });
264
-
265
- test('introspect (Phase 14): --table=inventory.products qualified → file emit schema: inventory', () => {
266
- withTmpDir((tmpRoot) => {
267
- const outDir = path.join(tmpRoot, 'schema');
268
- const result = runIntrospect(
269
- [`--config=${CONFIG_PG}`, `--output=${outDir}`, '--table=inventory.products'],
270
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_MULTI } }
271
- );
272
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
273
- assert.ok(fs.existsSync(path.join(outDir, 'products.js')));
274
- const content = fs.readFileSync(path.join(outDir, 'products.js'), 'utf8');
275
- assert.match(content, /schema: 'inventory'/);
276
- assert.match(content, /defineModel\('products'/);
277
- });
278
- });
279
-
280
- test('introspect (Phase 14): --schema=inventory --table=products (split style) → equivalent to qualified single', () => {
281
- withTmpDir((tmpRoot) => {
282
- const outDir = path.join(tmpRoot, 'schema');
283
- const result = runIntrospect(
284
- [`--config=${CONFIG_PG}`, `--output=${outDir}`, '--schema=inventory', '--table=products'],
285
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_MULTI } }
286
- );
287
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
288
- const content = fs.readFileSync(path.join(outDir, 'products.js'), 'utf8');
289
- assert.match(content, /schema: 'inventory'/);
290
- });
291
- });
292
-
293
- test('introspect (Phase 14): conflict --all-schemas + --schema → exit 1', () => {
294
- const result = runIntrospect(
295
- [`--config=${CONFIG_PG}`, '--output=./out', '--all-schemas', '--schema=inventory'],
296
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_ALL_SCHEMAS } }
297
- );
298
- assert.strictEqual(result.status, 1);
299
- assert.match(result.stderr, /--all-schemas conflicts with --schema/);
300
- });
301
-
302
- test('introspect (Phase 14): conflict --all-schemas + --table → exit 1', () => {
303
- const result = runIntrospect(
304
- [`--config=${CONFIG_PG}`, '--output=./out', '--all-schemas', '--table=foo'],
305
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_ALL_SCHEMAS } }
306
- );
307
- assert.strictEqual(result.status, 1);
308
- assert.match(result.stderr, /--all-schemas conflicts with --table/);
309
- });
310
-
311
- test('introspect (Phase 14): conflict --schema=foo + qualified --table=audit.events → exit 1', () => {
312
- const result = runIntrospect(
313
- [`--config=${CONFIG_PG}`, '--output=./out', '--schema=inventory', '--table=audit.events'],
314
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_MULTI } }
315
- );
316
- assert.strictEqual(result.status, 1);
317
- assert.match(result.stderr, /--schema conflicts with a qualified --table/);
318
- });
319
-
320
- test('introspect (Phase 14): default-schema bulk (no --schema/--all-schemas) backward compat — flat + no schema:', () => {
321
- withTmpDir((tmpRoot) => {
322
- const outDir = path.join(tmpRoot, 'schema');
323
- const result = runIntrospect(
324
- [`--config=${CONFIG_PG}`, `--output=${outDir}`],
325
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_TWO } }
326
- );
327
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
328
- const content = fs.readFileSync(path.join(outDir, 'category.js'), 'utf8');
329
- // Phase 12 stub does not set schemaName → output must NOT include schema: line
330
- assert.doesNotMatch(content, /^\s*schema:/m);
331
- // Flat layout
332
- assert.ok(!fs.existsSync(path.join(outDir, 'public')));
333
- });
334
- });
335
-
336
- test('introspect (Phase 14): multi-schema bulk dry-run → stdout banner per qualified table', () => {
337
- const result = runIntrospect(
338
- [`--config=${CONFIG_PG}`, '--dry-run', '--schema=inventory,audit'],
339
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_MULTI } }
340
- );
341
- assert.strictEqual(result.status, 2, `stderr: ${result.stderr}`);
342
- assert.match(result.stdout, /── inventory\.products /);
343
- assert.match(result.stdout, /── audit\.events /);
344
- assert.match(result.stdout, /schema: 'inventory'/);
345
- assert.match(result.stdout, /schema: 'audit'/);
346
- assert.match(result.stderr, /Dry-run complete: 4 table\(s\) previewed across 2 schema\(s\)/);
347
- });
348
-
349
- test('introspect (Phase 14): round-trip multi-schema → 4 model dengan schemaName valid', () => {
350
- withTmpDir((tmpRoot) => {
351
- const outDir = path.join(tmpRoot, 'schema');
352
- const result = runIntrospect(
353
- [`--config=${CONFIG_PG}`, `--output=${outDir}`, '--schema=inventory,audit'],
354
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_MULTI } }
355
- );
356
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
357
-
358
- const { loadSchemaPath } = require(path.join(REPO_ROOT, 'lib', 'dbschema-kit', 'loader'));
359
- const models = loadSchemaPath(outDir);
360
- assert.strictEqual(models.size, 4);
361
- assert.ok(models.has('inventory.products'));
362
- assert.ok(models.has('inventory.categories'));
363
- assert.ok(models.has('audit.events'));
364
- assert.ok(models.has('audit.logs'));
365
-
366
- const eventsIr = models.get('audit.events');
367
- assert.strictEqual(eventsIr.schemaName, 'audit');
368
- // FK target ke schema lain harus qualified
369
- const rels = Object.values(eventsIr.relations);
370
- assert.ok(rels.some(r => r.target === 'inventory.products'));
371
- });
372
- });
373
-
374
- test('introspect: round-trip — output bulk dapat di-load oleh loadSchemaPath', () => {
375
- withTmpDir((tmpRoot) => {
376
- const outDir = path.join(tmpRoot, 'schema');
377
- const result = runIntrospect(
378
- [`--config=${CONFIG_PG}`, `--output=${outDir}`],
379
- { env: { DBSCHEMA_KIT_TEST_INTROSPECT_STUB: STUB_TWO } }
380
- );
381
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
382
-
383
- const { loadSchemaPath } = require(path.join(REPO_ROOT, 'lib', 'dbschema-kit', 'loader'));
384
- const models = loadSchemaPath(outDir);
385
- assert.strictEqual(models.size, 2);
386
- assert.ok(models.has('category'));
387
- assert.ok(models.has('item_product'));
388
-
389
- const itemIr = models.get('item_product');
390
- assert.ok(itemIr.relations && Object.keys(itemIr.relations).length > 0,
391
- 'item_product harus punya relasi ke category');
392
- });
393
- });
@@ -1,104 +0,0 @@
1
- 'use strict';
2
-
3
- const test = require('node:test');
4
- const assert = require('node:assert');
5
- const path = require('node:path');
6
- const fs = require('node:fs');
7
- const os = require('node:os');
8
- const { spawnSync } = require('node:child_process');
9
-
10
- const REPO_ROOT = path.resolve(__dirname, '..', '..', '..', '..', '..');
11
- const CLI_SCRIPT = path.join(REPO_ROOT, 'cli', 'dbschema-generate-ddl.js');
12
- const FIXTURE_VALID = path.resolve(__dirname, '..', 'fixtures', 'integration', 'mini-inventory');
13
- const FIXTURE_INVALID = path.resolve(__dirname, '..', 'fixtures', 'integration', 'mini-inventory-invalid');
14
-
15
- function runGen(args, options = {}) {
16
- return spawnSync(process.execPath, [CLI_SCRIPT, ...args], {
17
- encoding: 'utf-8',
18
- env: { ...process.env, NO_COLOR: '1' },
19
- ...options
20
- });
21
- }
22
-
23
- test('generate-ddl: folder valid + --dialect=postgres → exit 0, stdout berisi CREATE TABLE', () => {
24
- const result = runGen([FIXTURE_VALID, '--dialect=postgres']);
25
- assert.strictEqual(result.status, 0, `expected exit 0, got ${result.status}. stderr: ${result.stderr}`);
26
- assert.match(result.stdout, /-- Generated by dbschema:generate-ddl/);
27
- assert.match(result.stdout, /CREATE TABLE category/);
28
- assert.match(result.stdout, /CREATE TABLE item_product/);
29
- // Topological order
30
- const catIdx = result.stdout.indexOf('CREATE TABLE category');
31
- const itemIdx = result.stdout.indexOf('CREATE TABLE item_product');
32
- assert.ok(catIdx < itemIdx, 'category harus muncul sebelum item_product');
33
- });
34
-
35
- test('generate-ddl: --out=<tempfile> → file ditulis dengan content sama dengan stdout default', () => {
36
- const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'dbschema-kit-gen-'));
37
- const outPath = path.join(tmpRoot, 'out.sql');
38
- try {
39
- const stdoutResult = runGen([FIXTURE_VALID, '--dialect=postgres']);
40
- assert.strictEqual(stdoutResult.status, 0);
41
-
42
- const fileResult = runGen([FIXTURE_VALID, '--dialect=postgres', `--out=${outPath}`]);
43
- assert.strictEqual(fileResult.status, 0, `stderr: ${fileResult.stderr}`);
44
- assert.strictEqual(fileResult.stdout, '', 'stdout harus kosong saat --out di-set');
45
-
46
- assert.ok(fs.existsSync(outPath), 'file output harus terbuat');
47
- const fileContent = fs.readFileSync(outPath, 'utf-8');
48
-
49
- // Buang baris timestamp untuk perbandingan (timestamp beda antar run)
50
- const stripTs = (s) => s.replace(/-- Generated at: [^\n]+/, '-- Generated at: <ts>');
51
- assert.strictEqual(stripTs(fileContent), stripTs(stdoutResult.stdout));
52
- } finally {
53
- fs.rmSync(tmpRoot, { recursive: true, force: true });
54
- }
55
- });
56
-
57
- test('generate-ddl: --drop=true → output mengandung DROP TABLE statement', () => {
58
- const result = runGen([FIXTURE_VALID, '--dialect=postgres', '--drop=true']);
59
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
60
- assert.match(result.stdout, /-- DROP section/);
61
- assert.match(result.stdout, /DROP TABLE IF EXISTS stock_inbound_item CASCADE;/);
62
- // DROP child sebelum DROP parent
63
- const dropChildIdx = result.stdout.indexOf('DROP TABLE IF EXISTS stock_inbound_item');
64
- const dropParentIdx = result.stdout.indexOf('DROP TABLE IF EXISTS stock_inbound CASCADE');
65
- assert.ok(dropChildIdx > 0 && dropParentIdx > 0);
66
- assert.ok(dropChildIdx < dropParentIdx, 'DROP child harus sebelum DROP parent');
67
- });
68
-
69
- test('generate-ddl: folder invalid (mini-inventory-invalid) → exit 1, stderr berisi error cross-model', () => {
70
- const result = runGen([FIXTURE_INVALID, '--dialect=postgres']);
71
- assert.strictEqual(result.status, 1, `expected exit 1, got ${result.status}`);
72
- assert.match(result.stderr, /Cross-model validation/);
73
- });
74
-
75
- test('generate-ddl: path tidak exist → exit 1, stderr berisi "Schema path not found"', () => {
76
- const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'dbschema-kit-gen-'));
77
- const ghost = path.join(tmpRoot, 'does-not-exist');
78
- try {
79
- const result = runGen([ghost, '--dialect=postgres']);
80
- assert.strictEqual(result.status, 1, `expected exit 1, got ${result.status}`);
81
- assert.match(result.stderr, /Schema path not found/);
82
- } finally {
83
- fs.rmSync(tmpRoot, { recursive: true, force: true });
84
- }
85
- });
86
-
87
- test('generate-ddl: --dialect tidak diberikan → exit 1, stderr berisi pesan error tentang dialect required', () => {
88
- const result = runGen([FIXTURE_VALID]);
89
- assert.strictEqual(result.status, 1, `expected exit 1, got ${result.status}`);
90
- assert.match(result.stderr, /--dialect is required/);
91
- });
92
-
93
- test('generate-ddl: --dialect=mssql (invalid) → exit 1, stderr berisi pesan error dialect tidak dikenal', () => {
94
- const result = runGen([FIXTURE_VALID, '--dialect=mssql']);
95
- assert.strictEqual(result.status, 1, `expected exit 1, got ${result.status}`);
96
- assert.match(result.stderr, /Unknown dialect 'mssql'/);
97
- });
98
-
99
- test('generate-ddl: --dialect=mysql menghasilkan output dengan identifier tanpa quote', () => {
100
- const result = runGen([FIXTURE_VALID, '--dialect=mysql']);
101
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
102
- assert.match(result.stdout, /CREATE TABLE category/);
103
- assert.match(result.stdout, /-- Dialect: mysql/);
104
- });
@@ -1,119 +0,0 @@
1
- 'use strict';
2
-
3
- const test = require('node:test');
4
- const assert = require('node:assert');
5
- const path = require('node:path');
6
- const fs = require('node:fs');
7
- const os = require('node:os');
8
- const { spawnSync } = require('node:child_process');
9
-
10
- const REPO_ROOT = path.resolve(__dirname, '..', '..', '..', '..', '..');
11
- const CLI_SCRIPT = path.join(REPO_ROOT, 'cli', 'dbschema-init.js');
12
-
13
- function runInit(args, options = {}) {
14
- return spawnSync(process.execPath, [CLI_SCRIPT, ...args], {
15
- encoding: 'utf-8',
16
- env: { ...process.env, NO_COLOR: '1' },
17
- ...options
18
- });
19
- }
20
-
21
- function withTmpDir(fn) {
22
- const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'dbsk-init-'));
23
- try {
24
- return fn(tmpRoot);
25
- } finally {
26
- fs.rmSync(tmpRoot, { recursive: true, force: true });
27
- }
28
- }
29
-
30
- test('init: --help → exit 0, stdout berisi usage', () => {
31
- const result = runInit(['--help']);
32
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
33
- assert.match(result.stdout, /dbschema Init/);
34
- assert.match(result.stdout, /<path>/);
35
- });
36
-
37
- test('init: tanpa argumen path → exit 1, stderr "Target file path is required"', () => {
38
- const result = runInit([]);
39
- assert.strictEqual(result.status, 1, `expected exit 1, got ${result.status}`);
40
- assert.match(result.stderr, /Target file path is required/);
41
- });
42
-
43
- test('init: file path tanpa ekstensi .js → exit 1, stderr "must have .js extension"', () => {
44
- withTmpDir((tmpRoot) => {
45
- const target = path.join(tmpRoot, 'supplier');
46
- const result = runInit([target]);
47
- assert.strictEqual(result.status, 1);
48
- assert.match(result.stderr, /must have \.js extension/);
49
- });
50
- });
51
-
52
- test('init: file sudah ada → exit 1, stderr "File already exists"', () => {
53
- withTmpDir((tmpRoot) => {
54
- const target = path.join(tmpRoot, 'supplier.js');
55
- fs.writeFileSync(target, '// existing');
56
- const result = runInit([target]);
57
- assert.strictEqual(result.status, 1);
58
- assert.match(result.stderr, /File already exists/);
59
- });
60
- });
61
-
62
- test('init: nama tabel invalid (mulai dengan angka) → exit 1', () => {
63
- withTmpDir((tmpRoot) => {
64
- const target = path.join(tmpRoot, '1invalid.js');
65
- const result = runInit([target]);
66
- assert.strictEqual(result.status, 1);
67
- assert.match(result.stderr, /Invalid table name/);
68
- });
69
- });
70
-
71
- test('init: happy path → exit 0, file dibuat dengan factory function pattern', () => {
72
- withTmpDir((tmpRoot) => {
73
- const target = path.join(tmpRoot, 'supplier.js');
74
- const result = runInit([target]);
75
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
76
- assert.match(result.stdout, /Created schema skeleton/);
77
- assert.ok(fs.existsSync(target), 'file harus dibuat');
78
- const content = fs.readFileSync(target, 'utf8');
79
- assert.match(content, /module\.exports = \(\{ defineModel \}\) => defineModel\('supplier'/);
80
- assert.match(content, /supplier_id: 'string:36 pk'/);
81
- assert.match(content, /relations:/);
82
- assert.match(content, /belongsTo/);
83
- });
84
- });
85
-
86
- test('init: parent folder dibuat otomatis bila belum ada', () => {
87
- withTmpDir((tmpRoot) => {
88
- const target = path.join(tmpRoot, 'nested', 'subfolder', 'order.js');
89
- const result = runInit([target]);
90
- assert.strictEqual(result.status, 0, `stderr: ${result.stderr}`);
91
- assert.ok(fs.existsSync(target));
92
- });
93
- });
94
-
95
- test('init: skeleton hasilnya dapat di-load oleh loader (factory function valid)', () => {
96
- withTmpDir((tmpRoot) => {
97
- const target = path.join(tmpRoot, 'item_product.js');
98
- const result = runInit([target]);
99
- assert.strictEqual(result.status, 0);
100
-
101
- const { loadSchemaPath } = require(path.join(REPO_ROOT, 'lib', 'dbschema-kit', 'loader'));
102
- const models = loadSchemaPath(target);
103
- assert.strictEqual(models.size, 1);
104
- const ir = models.get('item_product');
105
- assert.ok(ir, 'tableName harus terdaftar');
106
- assert.strictEqual(ir.tableName, 'item_product');
107
- assert.ok(ir.fields, 'fields harus ada');
108
- assert.ok(ir.relations, 'relations harus ada');
109
- });
110
- });
111
-
112
- test('init: unknown option → exit 1', () => {
113
- withTmpDir((tmpRoot) => {
114
- const target = path.join(tmpRoot, 'supplier.js');
115
- const result = runInit([target, '--unknown-flag']);
116
- assert.strictEqual(result.status, 1);
117
- assert.match(result.stderr, /Unknown option/);
118
- });
119
- });
@@ -1,48 +0,0 @@
1
- 'use strict';
2
-
3
- const test = require('node:test');
4
- const assert = require('node:assert');
5
- const path = require('node:path');
6
- const fs = require('node:fs');
7
- const os = require('node:os');
8
- const { spawnSync } = require('node:child_process');
9
-
10
- const REPO_ROOT = path.resolve(__dirname, '..', '..', '..', '..', '..');
11
- const CLI_SCRIPT = path.join(REPO_ROOT, 'cli', 'dbschema-models.js');
12
- const FIXTURE_VALID = path.resolve(__dirname, '..', 'fixtures', 'integration', 'mini-inventory');
13
-
14
- function runList(args, options = {}) {
15
- return spawnSync(process.execPath, [CLI_SCRIPT, ...args], {
16
- encoding: 'utf-8',
17
- env: { ...process.env, NO_COLOR: '1' },
18
- ...options
19
- });
20
- }
21
-
22
- test('list: folder valid (mini-inventory) → exit 0 dengan 6 nama tabel', () => {
23
- const result = runList([FIXTURE_VALID]);
24
- assert.strictEqual(result.status, 0, `expected exit 0, got ${result.status}. stderr: ${result.stderr}`);
25
- const expectedTables = ['category', 'supplier', 'warehouse', 'item_product', 'stock_inbound', 'stock_inbound_item'];
26
- for (const tbl of expectedTables) {
27
- assert.match(result.stdout, new RegExp(`\\b${tbl}\\b`), `tabel ${tbl} tidak ditemukan di output`);
28
- }
29
- assert.match(result.stdout, /6 models loaded\./);
30
- });
31
-
32
- test('list: folder valid → output mengandung header tabel ringkasan', () => {
33
- const result = runList([FIXTURE_VALID]);
34
- assert.strictEqual(result.status, 0);
35
- assert.match(result.stdout, /Schema\s+Table\s+Fields\s+PK\s+Indexes\s+Uniques\s+Relations/);
36
- });
37
-
38
- test('list: path tidak exist → exit 1 dengan pesan "Schema path not found"', () => {
39
- const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'dbschema-kit-list-'));
40
- const ghost = path.join(tmpRoot, 'does-not-exist');
41
- try {
42
- const result = runList([ghost]);
43
- assert.strictEqual(result.status, 1, `expected exit 1, got ${result.status}`);
44
- assert.match(result.stderr, /Schema path not found/);
45
- } finally {
46
- fs.rmSync(tmpRoot, { recursive: true, force: true });
47
- }
48
- });