@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,322 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Contract: schema diff
5
+ *
6
+ * Drift detection antara Schema Definition File (SDF) dan struktur tabel
7
+ * actual di database. Read-only. Tidak melakukan modifikasi pada filesystem
8
+ * maupun database.
9
+ *
10
+ * Algoritma bidirectional: tampilkan delta dari kedua sisi (only-in-SDF,
11
+ * only-in-DB, mismatched) di level IR (Intermediate Representation),
12
+ * bypass formatting noise.
13
+ */
14
+
15
+ const fs = require('fs');
16
+ const os = require('os');
17
+ const path = require('path');
18
+
19
+ const { loadSchemaPath } = require('../../lib/dbschema-kit/loader');
20
+ const { mapTableMetaToIR } = require('../../lib/dbschema-kit/introspect-mapper');
21
+ const { loadConfig } = require('../../lib/dbschema-kit/connection');
22
+ const { diffModels } = require('../../lib/dbschema-kit/diff-engine');
23
+ const { reportHuman, reportJson, getExitCode } = require('../../lib/dbschema-kit/diff-reporter');
24
+ const { resolveConfig, printDefaultConfigWarning } = require('../../lib/utils/config-resolver');
25
+
26
+ function loadIntrospector() {
27
+ const stubPath = process.env.DBSCHEMA_KIT_TEST_INTROSPECT_STUB;
28
+ if (stubPath) {
29
+ return require(path.resolve(stubPath));
30
+ }
31
+ return defaultIntrospector;
32
+ }
33
+
34
+ function mapDialectToDbType(dialect) {
35
+ switch (dialect) {
36
+ case 'postgres': return 'postgresql';
37
+ case 'mysql': return 'mysql';
38
+ case 'oracle': return 'oracle';
39
+ case 'sqlite': return 'sqlite';
40
+ default: return dialect;
41
+ }
42
+ }
43
+
44
+ function buildEphemeralEnvFile(config, dbType) {
45
+ const lines = [`DB_TYPE=${dbType}`];
46
+ if (config.host !== undefined) lines.push(`DB_HOST=${config.host}`);
47
+ if (config.port !== undefined) lines.push(`DB_PORT=${config.port}`);
48
+ if (dbType === 'oracle') {
49
+ lines.push(`DB_NAME=${config.serviceName || ''}`);
50
+ } else if (config.database !== undefined) {
51
+ lines.push(`DB_NAME=${config.database}`);
52
+ }
53
+ if (config.user !== undefined) lines.push(`DB_USER=${config.user}`);
54
+ if (config.password !== undefined) lines.push(`DB_PASSWORD=${config.password}`);
55
+ return lines.join('\n') + '\n';
56
+ }
57
+
58
+ function createTmpEnvFile(content) {
59
+ const tmpDir = os.tmpdir();
60
+ const tmpName = `restforge-diff-${process.pid}-${Date.now()}.env`;
61
+ const fullPath = path.join(tmpDir, tmpName);
62
+ fs.writeFileSync(fullPath, content, 'utf8');
63
+ return fullPath;
64
+ }
65
+
66
+ async function collectTableMeta(introspector, target) {
67
+ const ref = target.schemaName ? `${target.schemaName}.${target.tableName}` : target.tableName;
68
+ const detailedColumns = await introspector.getDetailedColumnInfo(ref);
69
+ const constraints = await introspector.getConstraints(ref);
70
+ const foreignKeys = await introspector.getForeignKeys(ref);
71
+ const indexes = await introspector.getIndexes(ref);
72
+
73
+ const pkConstraint = constraints.find((c) => c.type === 'PRIMARY KEY');
74
+ const uniqueConstraints = constraints
75
+ .filter((c) => c.type === 'UNIQUE')
76
+ .map((c) => ({ name: c.name, columns: c.columns }));
77
+
78
+ return {
79
+ tableName: target.tableName,
80
+ schemaName: target.schemaName || null,
81
+ columns: detailedColumns,
82
+ primaryKey: pkConstraint ? pkConstraint.columns : [],
83
+ uniques: uniqueConstraints,
84
+ foreignKeys,
85
+ indexes,
86
+ checks: []
87
+ };
88
+ }
89
+
90
+ const defaultIntrospector = {
91
+ introspect: async ({ config, tables }) => {
92
+ const dbType = mapDialectToDbType(config.dialect);
93
+ if (dbType === 'sqlite') {
94
+ throw new Error('schema:diff does not yet support sqlite. Use postgres, mysql, or oracle.');
95
+ }
96
+
97
+ const { DatabaseIntrospector } = require('../../lib/utils/database-introspector');
98
+ const introspector = new DatabaseIntrospector({ quiet: true });
99
+
100
+ const ephemeralEnv = buildEphemeralEnvFile(config, dbType);
101
+ const tmpPath = createTmpEnvFile(ephemeralEnv);
102
+
103
+ try {
104
+ const ok = introspector.loadConfig(tmpPath);
105
+ if (!ok) throw new Error('Failed to load config into DatabaseIntrospector');
106
+ const connected = await introspector.connect();
107
+ if (!connected) throw new Error('Failed to connect to database');
108
+
109
+ const out = [];
110
+ for (const target of tables) {
111
+ try {
112
+ out.push(await collectTableMeta(introspector, target));
113
+ } catch (err) {
114
+ // Tabel tidak ada di DB: catat dengan struktur kosong agar
115
+ // diff engine memperlakukannya sebagai "only-in-SDF" di sisi DB.
116
+ out.push({
117
+ tableName: target.tableName,
118
+ schemaName: target.schemaName || null,
119
+ columns: [],
120
+ primaryKey: [],
121
+ uniques: [],
122
+ foreignKeys: [],
123
+ indexes: [],
124
+ checks: [],
125
+ _missing: true,
126
+ _error: err && err.message ? err.message : String(err)
127
+ });
128
+ }
129
+ }
130
+ return { tables: out };
131
+ } finally {
132
+ try { await introspector.disconnect(); } catch (e) { /* ignore */ }
133
+ try { fs.unlinkSync(tmpPath); } catch (e) { /* ignore */ }
134
+ }
135
+ }
136
+ };
137
+
138
+ module.exports = {
139
+ resource: 'schema',
140
+ verb: 'diff',
141
+ description: 'Drift detection antara SDF dan struktur tabel database (read-only, bidirectional)',
142
+ category: 'introspection',
143
+ flags: {
144
+ path: {
145
+ type: 'string',
146
+ required: true,
147
+ description: 'Path file atau folder schema (mis. ./schema atau ./schema/users.js)'
148
+ },
149
+ config: {
150
+ type: 'string',
151
+ required: false,
152
+ default: null,
153
+ description: 'File config database (.env). Fallback ke `.restforge/defaults.json` bila tidak disediakan eksplisit (set via `config set-default`)'
154
+ },
155
+ table: {
156
+ type: 'string',
157
+ required: false,
158
+ default: null,
159
+ description: 'Diff hanya satu tabel spesifik (default: semua model di SDF)'
160
+ },
161
+ json: {
162
+ type: 'boolean',
163
+ required: false,
164
+ default: false,
165
+ description: 'Output format JSON (default: human-readable plain)'
166
+ }
167
+ },
168
+ examples: [
169
+ 'npx restforge schema diff --path=./schema --config=db.env',
170
+ 'npx restforge schema diff --path=./schema/visitors.js --config=db.env --table=visitors',
171
+ 'npx restforge schema diff --path=./schema --config=db.env --json'
172
+ ],
173
+ async handler(args) {
174
+ // 1. Resolve config
175
+ const resolvedConfigResult = resolveConfig(args.config, process.cwd());
176
+ if (!resolvedConfigResult) {
177
+ console.error('Error: --config=<file> is required.');
178
+ console.error("Tip: set a default with 'npx restforge config set-default --config=<file>' to omit --config in future runs");
179
+ const err = new Error('--config=<file> is required');
180
+ err.exitCode = 2;
181
+ throw err;
182
+ }
183
+
184
+ if (resolvedConfigResult.source === 'default') {
185
+ printDefaultConfigWarning(resolvedConfigResult.defaultName);
186
+ }
187
+
188
+ let config;
189
+ try {
190
+ config = loadConfig(resolvedConfigResult.path);
191
+ } catch (err) {
192
+ console.error(`Error: ${err.message}`);
193
+ const e = new Error(err.message);
194
+ e.exitCode = 2;
195
+ throw e;
196
+ }
197
+
198
+ // 2. Load SDF
199
+ const schemaPath = args.path;
200
+ const absPath = path.resolve(process.cwd(), schemaPath);
201
+
202
+ let sdfModels;
203
+ try {
204
+ sdfModels = loadSchemaPath(absPath);
205
+ } catch (err) {
206
+ console.error(`Error: ${err.message}`);
207
+ const e = new Error(err.message);
208
+ e.exitCode = 2;
209
+ throw e;
210
+ }
211
+
212
+ if (sdfModels.size === 0) {
213
+ console.error(`Error: No schema models found at '${schemaPath}'.`);
214
+ const e = new Error(`No schema models found at '${schemaPath}'`);
215
+ e.exitCode = 2;
216
+ throw e;
217
+ }
218
+
219
+ // 3. Resolve target tables
220
+ let targetEntries = Array.from(sdfModels.entries());
221
+ if (args.table) {
222
+ targetEntries = targetEntries.filter(([qualified, ir]) => {
223
+ return ir.tableName === args.table || qualified === args.table;
224
+ });
225
+ if (targetEntries.length === 0) {
226
+ console.error(`Error: Table '${args.table}' not found in SDF.`);
227
+ const e = new Error(`Table '${args.table}' not found in SDF`);
228
+ e.exitCode = 2;
229
+ throw e;
230
+ }
231
+ }
232
+
233
+ const targetsForDb = targetEntries.map(([_, ir]) => ({
234
+ tableName: ir.tableName,
235
+ schemaName: ir.schemaName || null
236
+ }));
237
+
238
+ // 4. Connect database, introspect setiap tabel
239
+ let introspector;
240
+ try {
241
+ introspector = loadIntrospector();
242
+ } catch (err) {
243
+ console.error(`Error: Failed to load introspector: ${err.message}`);
244
+ const e = new Error(err.message);
245
+ e.exitCode = 2;
246
+ throw e;
247
+ }
248
+
249
+ let result;
250
+ try {
251
+ result = await introspector.introspect({ config, tables: targetsForDb });
252
+ } catch (err) {
253
+ const message = err && err.message ? err.message : String(err);
254
+ console.error(`Error: ${message}`);
255
+ const e = new Error(message);
256
+ e.exitCode = 2;
257
+ throw e;
258
+ }
259
+
260
+ if (!result || !Array.isArray(result.tables)) {
261
+ console.error('Error: Introspector did not return a tables array.');
262
+ const e = new Error('Introspector did not return a tables array');
263
+ e.exitCode = 2;
264
+ throw e;
265
+ }
266
+
267
+ // 5. Map DB results to IR (keyed by tableName supaya match dengan SDF)
268
+ const dialect = config.dialect;
269
+ const dbModels = new Map();
270
+ for (const tableMeta of result.tables) {
271
+ if (tableMeta._missing) {
272
+ // Tabel hilang di DB: register empty IR agar diff engine
273
+ // memperlakukan sebagai onlyInSdf untuk seluruh content.
274
+ const qualified = tableMeta.schemaName
275
+ ? `${tableMeta.schemaName}.${tableMeta.tableName}`
276
+ : tableMeta.tableName;
277
+ dbModels.set(qualified, {
278
+ tableName: tableMeta.tableName,
279
+ schemaName: tableMeta.schemaName || null,
280
+ qualifiedName: qualified,
281
+ fields: {},
282
+ primaryKey: [],
283
+ indexes: [],
284
+ uniques: [],
285
+ relations: {},
286
+ checks: []
287
+ });
288
+ continue;
289
+ }
290
+ const ir = mapTableMetaToIR(tableMeta, dialect);
291
+ dbModels.set(ir.qualifiedName || ir.tableName, ir);
292
+ }
293
+
294
+ // 6. Build SDF map matching same key convention as dbModels
295
+ const sdfMap = new Map();
296
+ for (const [_, ir] of targetEntries) {
297
+ sdfMap.set(ir.qualifiedName || ir.tableName, ir);
298
+ }
299
+
300
+ // 7. Compute diff
301
+ const deltas = diffModels(sdfMap, dbModels);
302
+
303
+ // 8. Report
304
+ if (args.json) {
305
+ const obj = reportJson(deltas);
306
+ process.stdout.write(JSON.stringify(obj, null, 2));
307
+ process.stdout.write('\n');
308
+ } else {
309
+ const text = reportHuman(deltas);
310
+ process.stdout.write(text);
311
+ process.stdout.write('\n');
312
+ }
313
+
314
+ // 9. Exit code
315
+ const exitCode = getExitCode(deltas);
316
+ if (exitCode !== 0) {
317
+ const err = new Error(`schema diff detected drift in ${deltas.filter((d) => d.hasDrift).length} table(s)`);
318
+ err.exitCode = exitCode;
319
+ throw err;
320
+ }
321
+ }
322
+ };
@@ -27,6 +27,11 @@ module.exports = {
27
27
  description: 'Generate DDL SQL (CREATE TABLE, CREATE INDEX, opsional DROP) untuk seluruh schema models',
28
28
  category: 'generation',
29
29
  flags: {
30
+ path: {
31
+ type: 'string',
32
+ required: true,
33
+ description: 'Path file atau folder schema (mis. ./schema atau ./schema/users.js)'
34
+ },
30
35
  dialect: {
31
36
  type: 'string',
32
37
  required: true,
@@ -45,17 +50,9 @@ module.exports = {
45
50
  description: 'Sertakan statement DROP TABLE sebelum CREATE'
46
51
  }
47
52
  },
48
- positional: [
49
- {
50
- name: 'path',
51
- type: 'string',
52
- required: true,
53
- description: 'Path file atau folder schema'
54
- }
55
- ],
56
53
  examples: [
57
- 'npx restforge schema generate-ddl ./schema --dialect=postgres --out=migration.sql',
58
- 'npx restforge schema generate-ddl ./schema --dialect=mysql --drop=true'
54
+ 'npx restforge schema generate-ddl --path=./schema --dialect=postgres --out=migration.sql',
55
+ 'npx restforge schema generate-ddl --path=./schema --dialect=mysql --drop=true'
59
56
  ],
60
57
  async handler(args) {
61
58
  if (!args.dialect) {
@@ -1,172 +1,95 @@
1
- 'use strict';
2
-
3
- /**
4
- * Contract: schema init
5
- *
6
- * Create a skeleton schema definition file. The table name is derived from the
7
- * target filename (without `.js` extension). The skeleton is a complete example
8
- * including fields, indexes, uniques, and relations.
9
- *
10
- * Inline migration v4.0.0: business logic dari dbschema-init.js
11
- * dipindah ke handler.
12
- */
13
-
14
- const fs = require('fs');
15
- const path = require('path');
16
-
17
- function buildSkeleton(tableName) {
18
- const omitFkExample = tableName === 'table_parent';
19
-
20
- const fkField = omitFkExample
21
- ? ''
22
- : `
23
- // Foreign key placeholder (rename to actual parent column; relation declared below)
24
- table_parent_id: 'string:36 notnull',
25
- `;
26
-
27
- const uniquesEntry = omitFkExample
28
- ? ` ['${tableName}_code', '${tableName}_name']`
29
- : ` ['${tableName}_code', 'table_parent_id']`;
30
-
31
- const indexesEntry = omitFkExample
32
- ? ` '${tableName}_name',
33
- ['${tableName}_code', 'is_active']`
34
- : ` '${tableName}_name',
35
- ['table_parent_id', 'is_active']`;
36
-
37
- const relationsBlock = omitFkExample
38
- ? ''
39
- : `,
40
-
41
- // Relations to parent tables (belongsTo only at this layer)
42
- relations: {
43
- parent: {
44
- type: 'belongsTo',
45
- target: 'table_parent',
46
- localKey: 'table_parent_id',
47
- references: 'table_parent_id',
48
- onDelete: 'restrict'
49
- }
50
- }`;
51
-
52
- return `'use strict';
53
-
54
- /**
55
- * Schema definition for \`${tableName}\`
56
- *
57
- * Generated by: npx restforge schema init
58
- * Adjust fields, indexes, uniques, and relations to match the actual table.
59
- */
60
- module.exports = ({ defineModel }) => defineModel('${tableName}', {
61
- fields: {
62
- // Primary key (string:36 fits a UUID; backend defaults to uuidv7 at insert)
63
- ${tableName}_id: 'string:36 pk',
64
-
65
- // Required fields with simple constraints
66
- ${tableName}_code: 'string:20 unique notnull',
67
- ${tableName}_name: 'string:100 notnull',
68
-
69
- // Optional field with default
70
- is_active: 'boolean default:true',
71
-
72
- // Numeric: decimal:precision,scale
73
- credit_limit: 'decimal:18,2 default:0',
74
-
75
- // String column constrained by CHECK (defined in checks: section below)
76
- status: "string:20 notnull default:'active'",
77
- ${fkField}
78
- // Audit columns (RESTForge 4-column convention)
79
- // See dbschema:catalog --section=auditColumns for the full spec.
80
- // The same 4 columns are referenced by field-validation:catalog
81
- // auditColumns on the RDF/backend side, so SDF and RDF stay aligned.
82
- created_at: 'timestamp default:now()',
83
- created_by: 'string:100',
84
- updated_at: 'timestamp autoUpdate',
85
- updated_by: 'string:100'
86
- },
87
-
88
- // Composite uniques (single-column unique uses shorthand on field above)
89
- uniques: [
90
- ${uniquesEntry}
91
- ],
92
-
93
- // Indexes for query performance (single column or composite)
94
- indexes: [
95
- ${indexesEntry}
96
- ],
97
-
98
- // CHECK constraints (operators: in, gt, gte, lt, lte, eq, neq)
99
- checks: [
100
- { field: 'status', in: ['active', 'inactive', 'suspended'] },
101
- { field: 'credit_limit', gte: 0 }
102
- ]${relationsBlock}
103
- });
104
- `;
105
- }
106
-
107
- module.exports = {
108
- resource: 'schema',
109
- verb: 'init',
110
- description: 'Membuat skeleton file schema definition (fields, indexes, uniques, relations)',
111
- category: 'utility',
112
- flags: {},
113
- positional: [
114
- {
115
- name: 'path',
116
- type: 'string',
117
- required: true,
118
- description: 'Path file schema yang akan dibuat (mis. schema/users.js)'
119
- }
120
- ],
121
- examples: [
122
- 'npx restforge schema init schema/users.js',
123
- 'npx restforge schema init ./schema/item_product.js'
124
- ],
125
- async handler(args) {
126
- if (!args.path) {
127
- console.error('Error: Target file path is required.');
128
- console.error("Run 'npx restforge schema init --help' for usage information");
129
- throw new Error('Target file path is required');
130
- }
131
-
132
- const absPath = path.resolve(process.cwd(), args.path);
133
-
134
- if (path.extname(absPath) !== '.js') {
135
- console.error(`Error: Schema file must have .js extension: ${absPath}`);
136
- throw new Error(`Schema file must have .js extension: ${absPath}`);
137
- }
138
-
139
- if (fs.existsSync(absPath)) {
140
- console.error(`Error: File already exists: ${absPath}`);
141
- throw new Error(`File already exists: ${absPath}`);
142
- }
143
-
144
- const tableName = path.basename(absPath, '.js');
145
- if (!/^[a-z][a-z0-9_]*$/i.test(tableName)) {
146
- console.error(
147
- `Error: Invalid table name '${tableName}' (derived from filename). ` +
148
- `Must start with a letter and contain only letters, digits, or underscore.`
149
- );
150
- throw new Error(`Invalid table name '${tableName}' (derived from filename)`);
151
- }
152
-
153
- const parentDir = path.dirname(absPath);
154
- try {
155
- fs.mkdirSync(parentDir, { recursive: true });
156
- } catch (err) {
157
- console.error(`Error: Failed to create directory '${parentDir}': ${err.message}`);
158
- throw new Error(`Failed to create directory '${parentDir}': ${err.message}`);
159
- }
160
-
161
- try {
162
- fs.writeFileSync(absPath, buildSkeleton(tableName), 'utf8');
163
- } catch (err) {
164
- console.error(`Error: Failed to write file '${absPath}': ${err.message}`);
165
- throw new Error(`Failed to write file '${absPath}': ${err.message}`);
166
- }
167
-
168
- console.log(`✓ Created schema skeleton: ${absPath}`);
169
- console.log(` Table name: ${tableName}`);
170
- console.log(' Edit fields, indexes, uniques, and relations to match the actual table.');
171
- }
172
- };
1
+ 'use strict';
2
+
3
+ /**
4
+ * Contract: schema init
5
+ *
6
+ * Thin wrapper untuk scaffold file schema definition. Implementasi sekarang
7
+ * mendelegasikan ke binary native sdf-tools.exe dengan template `dummy`,
8
+ * menggantikan generator skeleton custom yang sebelumnya inline.
9
+ *
10
+ * Setara dengan: sdf-tools.exe --table=dummy --generate --lang=sdf --path=<USER_PATH>
11
+ *
12
+ * Kontrak CLI dipertahankan (verb, category, flag --path) agar workflow user
13
+ * tidak breaking. File yang dihasilkan berisi struktur template `dummy` dari
14
+ * koleksi RestForge Schema Reference, yang dapat di-rename dan diadaptasi
15
+ * sesuai kebutuhan.
16
+ */
17
+
18
+ const fs = require('fs');
19
+ const os = require('os');
20
+ const path = require('path');
21
+ const { spawnSync } = require('child_process');
22
+
23
+ function resolveBinaryPath() {
24
+ if (os.platform() !== 'win32') return null;
25
+ return path.resolve(__dirname, '..', '..', '..', 'bin', 'sdf-tools.exe');
26
+ }
27
+
28
+ module.exports = {
29
+ resource: 'schema',
30
+ verb: 'init',
31
+ description: 'Membuat skeleton file schema definition (delegate ke sdf-tools dengan template dummy)',
32
+ category: 'utility',
33
+ flags: {
34
+ path: {
35
+ type: 'string',
36
+ required: true,
37
+ description: 'Path file schema yang akan dibuat (mis. schema/users.js)'
38
+ }
39
+ },
40
+ examples: [
41
+ 'npx restforge schema init --path=schema/users.js',
42
+ 'npx restforge schema init --path=./schema/item_product.js'
43
+ ],
44
+ async handler(args) {
45
+ if (!args.path) {
46
+ console.error('Error: Target file path is required.');
47
+ console.error("Run 'npx restforge schema init --help' for usage information");
48
+ throw new Error('Target file path is required');
49
+ }
50
+
51
+ const binaryPath = resolveBinaryPath();
52
+ if (!binaryPath) {
53
+ const err = new Error(
54
+ `schema init hanya tersedia di Windows (sdf-tools.exe). Platform saat ini: ${os.platform()}`
55
+ );
56
+ err.exitCode = 3;
57
+ throw err;
58
+ }
59
+
60
+ if (!fs.existsSync(binaryPath)) {
61
+ const err = new Error(
62
+ `sdf-tools.exe tidak ditemukan di ${binaryPath}. ` +
63
+ 'Pastikan binary sudah di-build dan tersedia di folder bin/ package.'
64
+ );
65
+ err.exitCode = 3;
66
+ throw err;
67
+ }
68
+
69
+ const binaryArgs = [
70
+ '--table=dummy',
71
+ '--generate',
72
+ '--lang=sdf',
73
+ `--path=${args.path}`
74
+ ];
75
+
76
+ const result = spawnSync(binaryPath, binaryArgs, {
77
+ stdio: 'inherit',
78
+ windowsHide: true
79
+ });
80
+
81
+ if (result.error) {
82
+ const err = new Error(`Gagal menjalankan sdf-tools.exe: ${result.error.message}`);
83
+ err.exitCode = 1;
84
+ throw err;
85
+ }
86
+
87
+ const status = typeof result.status === 'number' ? result.status : 1;
88
+ if (status !== 0) {
89
+ const err = new Error(`sdf-tools.exe exit code ${status}`);
90
+ err.exitCode = status;
91
+ err.silent = true;
92
+ throw err;
93
+ }
94
+ }
95
+ };
@@ -238,8 +238,9 @@ module.exports = {
238
238
  flags: {
239
239
  config: {
240
240
  type: 'string',
241
- required: true,
242
- description: 'File config database (.env)'
241
+ required: false,
242
+ default: null,
243
+ description: 'File config database (.env). Fallback ke `.restforge/defaults.json` bila tidak disediakan eksplisit (set via `config set-default`)'
243
244
  },
244
245
  output: {
245
246
  type: 'string',
@@ -23,8 +23,9 @@ module.exports = {
23
23
  flags: {
24
24
  config: {
25
25
  type: 'string',
26
- required: true,
27
- description: 'File config database (.env)'
26
+ required: false,
27
+ default: null,
28
+ description: 'File config database (.env). Fallback ke `.restforge/defaults.json` bila tidak disediakan eksplisit (set via `config set-default`)'
28
29
  },
29
30
  schema: {
30
31
  type: 'string',