@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.
- package/SECURITY.md +83 -4
- package/bin/sdf-tools.exe +0 -0
- package/build-info.json +2 -2
- package/cli/consumer-deploy.js +1 -1
- package/cli/consumer.js +1 -1
- package/generators/cli/dashboard/create.js +4 -1
- package/generators/cli/endpoint/create.js +43 -4
- package/generators/cli/key/generate.js +2 -1
- package/generators/cli/key/revoke.js +2 -1
- package/generators/cli/payload/diff.js +3 -2
- package/generators/cli/payload/generate.js +3 -2
- package/generators/cli/payload/sync.js +3 -2
- package/generators/cli/payload/validate.js +3 -2
- package/generators/cli/processor/create.js +14 -3
- package/generators/cli/project/delete.js +2 -1
- package/generators/cli/query/validate.js +3 -2
- package/generators/cli/schema/apply.js +526 -0
- package/generators/cli/schema/describe.js +3 -2
- package/generators/cli/schema/diff.js +322 -0
- package/generators/cli/schema/generate-ddl.js +7 -10
- package/generators/cli/schema/init.js +95 -172
- package/generators/cli/schema/introspect.js +3 -2
- package/generators/cli/schema/list.js +3 -2
- package/generators/cli/schema/migrate.js +13 -18
- package/generators/cli/schema/models.js +8 -12
- package/generators/cli/schema/template.js +222 -0
- package/generators/cli/schema/validate.js +8 -12
- package/generators/cli-entry.js +17 -2
- package/generators/lib/dbschema-kit/apply-engine.js +582 -0
- package/generators/lib/dbschema-kit/diff-engine.js +703 -0
- package/generators/lib/dbschema-kit/diff-reporter.js +272 -0
- package/generators/lib/dbschema-kit/emitters/alter-table.js +275 -0
- package/generators/lib/migration/audit-table-runner.js +213 -215
- package/generators/lib/payload/endpoint-schema-validator.js +171 -0
- package/generators/lib/payload/payload-runner.js +137 -220
- package/generators/lib/payload/schema-diff.js +277 -0
- package/generators/lib/templates/dashboard-catalog.js +1 -437
- package/generators/lib/templates/db-connection-env.js +1 -212
- package/generators/lib/templates/dbschema-catalog.js +1 -489
- package/generators/lib/templates/field-validation-catalog.js +1 -531
- package/generators/lib/templates/mysql-template.js +1 -3863
- package/generators/lib/templates/oracle-template.js +1 -3915
- package/generators/lib/templates/postgres-template.js +1 -5838
- package/generators/lib/templates/query-declarative-catalog.js +1 -199
- package/generators/lib/templates/sqlite-template.js +1 -3440
- package/generators/lib/utils/audit-columns.js +181 -0
- package/generators/lib/utils/cli-output.js +17 -0
- package/generators/lib/utils/database-introspector.js +16 -13
- package/generators/lib/utils/env-manager.js +6 -0
- package/generators/lib/utils/path-validator.js +71 -0
- package/generators/lib/validators/payload-validator.js +1 -2
- package/integrity-manifest.json +28 -10
- package/package.json +11 -3
- package/scripts/verify-integrity.js +1 -1
- package/server.js +1 -1
- package/src/components/handlers/adjust_handler.js +1 -1
- package/src/components/handlers/audit_handler.js +1 -1
- package/src/components/handlers/delete_handler.js +1 -1
- package/src/components/handlers/export_handler.js +1 -1
- package/src/components/handlers/import_handler.js +1 -1
- package/src/components/handlers/insert_handler.js +1 -1
- package/src/components/handlers/update_handler.js +1 -1
- package/src/components/handlers/upload_handler.js +1 -1
- package/src/components/handlers/workflow_handler.js +1 -1
- package/src/components/integrations/webhook.js +1 -1
- package/src/consumers/baseConsumer.js +1 -1
- package/src/consumers/declarativeMapper.js +1 -1
- package/src/consumers/handlers/apiHandler.js +1 -1
- package/src/consumers/handlers/consoleHandler.js +1 -1
- package/src/consumers/handlers/databaseHandler.js +1 -1
- package/src/consumers/handlers/index.js +1 -1
- package/src/consumers/handlers/kafkaHandler.js +1 -1
- package/src/consumers/index.js +1 -1
- package/src/consumers/messageTransformer.js +1 -1
- package/src/consumers/validator.js +1 -1
- package/src/core/db/dialect/base-dialect.js +1 -1
- package/src/core/db/dialect/index.js +1 -1
- package/src/core/db/dialect/mysql-dialect.js +1 -1
- package/src/core/db/dialect/oracle-dialect.js +1 -1
- package/src/core/db/dialect/postgres-dialect.js +1 -1
- package/src/core/db/dialect/sqlite-dialect.js +1 -1
- package/src/core/db/flatten-helper.js +1 -1
- package/src/core/db/query-builder-error.js +1 -1
- package/src/core/db/query-builder.js +1 -1
- package/src/core/db/relation-helper.js +1 -1
- package/src/core/handlers/delete_handler.js +1 -1
- package/src/core/handlers/insert_handler.js +1 -1
- package/src/core/handlers/update_handler.js +1 -1
- package/src/core/models/base-model.js +1 -1
- package/src/core/utils/cache-manager.js +1 -1
- package/src/core/utils/component-engine.js +1 -1
- package/src/core/utils/context-builder.js +1 -1
- package/src/core/utils/datetime-formatter.js +1 -1
- package/src/core/utils/datetime-parser.js +1 -1
- package/src/core/utils/db.js +1 -1
- package/src/core/utils/logger.js +1 -1
- package/src/core/utils/payload-loader.js +1 -1
- package/src/core/utils/security-checks.js +1 -1
- package/src/middleware/body-options.js +1 -1
- package/src/middleware/cors.js +1 -1
- package/src/middleware/idempotency.js +1 -1
- package/src/middleware/rate-limiter.js +1 -1
- package/src/middleware/request-logger.js +1 -1
- package/src/middleware/security-headers.js +1 -1
- package/src/models/base-model-mysql.js +1 -1
- package/src/models/base-model-oracle.js +1 -1
- package/src/models/base-model-sqlite.js +1 -1
- package/src/models/base-model.js +1 -1
- package/src/pro/caching/redis-client.js +1 -1
- package/src/pro/caching/redis-helper.js +1 -1
- package/src/pro/consumers/baseConsumer.js +1 -1
- package/src/pro/consumers/declarativeMapper.js +1 -1
- package/src/pro/consumers/handlers/apiHandler.js +1 -1
- package/src/pro/consumers/handlers/consoleHandler.js +1 -1
- package/src/pro/consumers/handlers/databaseHandler.js +1 -1
- package/src/pro/consumers/handlers/index.js +1 -1
- package/src/pro/consumers/handlers/kafkaHandler.js +1 -1
- package/src/pro/consumers/index.js +1 -1
- package/src/pro/consumers/messageTransformer.js +1 -1
- package/src/pro/consumers/validator.js +1 -1
- package/src/pro/database/base-model-mysql.js +1 -1
- package/src/pro/database/base-model-oracle.js +1 -1
- package/src/pro/database/base-model-sqlite.js +1 -1
- package/src/pro/database/db-mysql.js +1 -1
- package/src/pro/database/db-oracle.js +1 -1
- package/src/pro/database/db-sqlite.js +1 -1
- package/src/pro/excel/excel-generator.js +1 -1
- package/src/pro/excel/excel-parser.js +1 -1
- package/src/pro/excel/export-service.js +1 -1
- package/src/pro/excel/export_handler.js +1 -1
- package/src/pro/excel/import-service.js +1 -1
- package/src/pro/excel/import-validator.js +1 -1
- package/src/pro/excel/import_handler.js +1 -1
- package/src/pro/excel/upsert-builder.js +1 -1
- package/src/pro/idgen/idgen-routes.js +1 -1
- package/src/pro/integrations/lookup-resolver.js +1 -1
- package/src/pro/integrations/upload-handler-v2.js +1 -1
- package/src/pro/integrations/upload-handler.js +1 -1
- package/src/pro/integrations/webhook.js +1 -1
- package/src/pro/locking/lock-routes.js +1 -1
- package/src/pro/locking/resource-lock-manager.js +1 -1
- package/src/pro/messaging/kafkaConsumerService.js +1 -1
- package/src/pro/messaging/kafkaService.js +1 -1
- package/src/pro/messaging/messagehubService.js +1 -1
- package/src/pro/messaging/rabbitmqService.js +1 -1
- package/src/pro/scheduler/job-manager.js +1 -1
- package/src/pro/scheduler/job-routes.js +1 -1
- package/src/pro/scheduler/job-validator.js +1 -1
- package/src/pro/storage/base-storage-provider.js +1 -1
- package/src/pro/storage/file-metadata-helper.js +1 -1
- package/src/pro/storage/index.js +1 -1
- package/src/pro/storage/local-storage-provider.js +1 -1
- package/src/pro/storage/s3-storage-provider.js +1 -1
- package/src/pro/storage/upload-cleanup-job.js +1 -1
- package/src/pro/storage/upload-cleanup-scheduler.js +1 -1
- package/src/pro/storage/upload-pending-tracker.js +1 -1
- package/src/pro/websocket/broadcast-helper.js +1 -1
- package/src/pro/websocket/index.js +1 -1
- package/src/pro/websocket/livesync-server.js +1 -1
- package/src/pro/websocket/ws-broadcaster.js +1 -1
- package/src/services/export-service.js +1 -1
- package/src/services/import-service.js +1 -1
- package/src/services/kafkaConsumerService.js +1 -1
- package/src/services/kafkaService.js +1 -1
- package/src/services/messagehubService.js +1 -1
- package/src/services/rabbitmqService.js +1 -1
- package/src/utils/cache-invalidation-registry.js +1 -1
- package/src/utils/cache-manager.js +1 -1
- package/src/utils/component-engine.js +1 -1
- package/src/utils/config-extractor.js +1 -1
- package/src/utils/consumerLogger.js +1 -1
- package/src/utils/context-builder.js +1 -1
- package/src/utils/dashboard-helpers.js +1 -1
- package/src/utils/dateHelper.js +1 -1
- package/src/utils/datetime-formatter.js +1 -1
- package/src/utils/datetime-parser.js +1 -1
- package/src/utils/db-bootstrap.js +1 -1
- package/src/utils/db-mysql.js +1 -1
- package/src/utils/db-oracle.js +1 -1
- package/src/utils/db-sqlite.js +1 -1
- package/src/utils/db.js +1 -1
- package/src/utils/demo-generator.js +1 -1
- package/src/utils/excel-generator.js +1 -1
- package/src/utils/excel-parser.js +1 -1
- package/src/utils/file-watcher.js +1 -1
- package/src/utils/id-generator.js +1 -1
- package/src/utils/idempotency-manager.js +1 -1
- package/src/utils/import-validator.js +1 -1
- package/src/utils/license-client.js +1 -1
- package/src/utils/lock-manager.js +1 -1
- package/src/utils/logger.js +1 -1
- package/src/utils/lookup-resolver.js +1 -1
- package/src/utils/payload-loader.js +1 -1
- package/src/utils/processor-response.js +1 -1
- package/src/utils/rabbitmq.js +1 -1
- package/src/utils/redis-client.js +1 -1
- package/src/utils/redis-helper.js +1 -1
- package/src/utils/request-scope.js +1 -1
- package/src/utils/security-checks.js +1 -1
- package/src/utils/service-resolver.js +1 -1
- package/src/utils/shutdown-coordinator.js +1 -1
- package/src/utils/trusted-keys.js +1 -1
- package/src/utils/upload-handler.js +1 -1
- package/src/utils/upsert-builder.js +1 -1
- package/src/utils/workflow-hook-executor.js +1 -1
- package/generators/metadata/global.json +0 -58
- package/generators/metadata/test-mysql-workbench.json +0 -118
- package/generators/metadata/test-mysql.json +0 -56
- package/generators/metadata/test-oracle-workbench.json +0 -118
- package/generators/metadata/test-oracle.json +0 -56
- package/generators/metadata/test-pg-workbench.json +0 -118
- package/generators/metadata/test-pg.json +0 -56
- package/generators/scripts/obfuscate-source.js +0 -356
- package/generators/scripts/validate-catalog.js +0 -430
- package/generators/scripts/validate-dbschema-catalog.js +0 -708
- package/generators/tests/baseline/mysql/mini_inventory_item/src/models/mini-inventory/item.js +0 -944
- package/generators/tests/baseline/mysql/mini_inventory_item/src/modules/mini-inventory/item.js +0 -740
- package/generators/tests/baseline/mysql/mini_inventory_item/src/modules/mini-inventory.js +0 -336
- package/generators/tests/baseline/oracle/mini_inventory_item/src/models/mini-inventory/item.js +0 -1002
- package/generators/tests/baseline/oracle/mini_inventory_item/src/modules/mini-inventory/item.js +0 -740
- package/generators/tests/baseline/oracle/mini_inventory_item/src/modules/mini-inventory.js +0 -336
- package/generators/tests/baseline/postgres/mini_inventory_item/src/models/mini-inventory/item.js +0 -1333
- package/generators/tests/baseline/postgres/mini_inventory_item/src/modules/mini-inventory/item.js +0 -1173
- package/generators/tests/baseline/postgres/mini_inventory_item/src/modules/mini-inventory.js +0 -496
- package/generators/tests/fixtures/payloads/custom-sensitive.json +0 -27
- package/generators/tests/fixtures/payloads/dynamic-search-optout.json +0 -23
- package/generators/tests/fixtures/payloads/login-with-password.json +0 -22
- package/generators/tests/fixtures/payloads/order-process.json +0 -52
- package/generators/tests/fixtures/payloads/with-inline-sql.json +0 -26
- package/generators/tests/integration-tahap4b/README.md +0 -145
- package/generators/tests/integration-tahap4b/run-concurrent.js +0 -77
- package/generators/tests/integration-tahap4b/seed.sql +0 -53
- package/generators/tests/integration-tahap4b/verify.sql +0 -110
- package/generators/tests/unit/cli/create-dashboard.test.js +0 -505
- package/generators/tests/unit/cli/create-processor.test.js +0 -319
- package/generators/tests/unit/cli/dispatch-dashboard.test.js +0 -149
- package/generators/tests/unit/lib/dashboard-generator.test.js +0 -895
- package/generators/tests/unit/lib/dashboard-validator.test.js +0 -354
- package/generators/tests/unit/lib/dbschema-kit/apply-executor.test.js +0 -437
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-introspect.test.js +0 -393
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-generate-ddl.test.js +0 -104
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-init.test.js +0 -119
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-list.test.js +0 -48
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-migrate.test.js +0 -175
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-kit-validate.test.js +0 -102
- package/generators/tests/unit/lib/dbschema-kit/cli/dbschema-models.test.js +0 -43
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/all-schemas-listing.js +0 -84
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/connection-error.js +0 -13
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/empty.js +0 -12
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/multi-schema.js +0 -124
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/single-schema-inventory.js +0 -64
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/introspect-stubs/two-tables.js +0 -66
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/migrate-stubs/connection-error.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/migrate-stubs/partial.js +0 -29
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/migrate-stubs/rollback.js +0 -26
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/migrate-stubs/success.js +0 -43
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/multi-schema/audit/events.js +0 -18
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/multi-schema/inventory/products.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/cli/fixtures/multi-schema/users.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/connection.test.js +0 -112
- package/generators/tests/unit/lib/dbschema-kit/ddl-generator.test.js +0 -205
- package/generators/tests/unit/lib/dbschema-kit/define-model.test.js +0 -56
- package/generators/tests/unit/lib/dbschema-kit/dialect/index.test.js +0 -46
- package/generators/tests/unit/lib/dbschema-kit/dialect/mysql.test.js +0 -126
- package/generators/tests/unit/lib/dbschema-kit/dialect/oracle.test.js +0 -126
- package/generators/tests/unit/lib/dbschema-kit/dialect/postgres.test.js +0 -131
- package/generators/tests/unit/lib/dbschema-kit/dialect/sqlite.test.js +0 -126
- package/generators/tests/unit/lib/dbschema-kit/driver-loader.test.js +0 -93
- package/generators/tests/unit/lib/dbschema-kit/emitters/create-index.test.js +0 -173
- package/generators/tests/unit/lib/dbschema-kit/emitters/create-table.test.js +0 -376
- package/generators/tests/unit/lib/dbschema-kit/emitters/drop-table.test.js +0 -78
- package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/invalid-dialect.env +0 -6
- package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/missing-dialect.env +0 -5
- package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/missing-host.env +0 -5
- package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/oracle-valid.env +0 -6
- package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/postgres-valid.env +0 -7
- package/generators/tests/unit/lib/dbschema-kit/fixtures/connection/sqlite-valid.env +0 -2
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/category.js +0 -11
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/item_product.js +0 -11
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/stock_inbound.js +0 -24
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/stock_inbound_item.js +0 -28
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/supplier.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/warehouse.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-invalid/orphan.js +0 -17
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/master/category.js +0 -11
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/master/item_product.js +0 -11
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/master/supplier.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/master/warehouse.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/transactions/stock_inbound.js +0 -24
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory-multifolder/transactions/stock_inbound_item.js +0 -28
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/multi-schema/audit/events.js +0 -18
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/multi-schema/inventory/products.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/multi-schema/public/users.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/duplicate-subfolder/extra/category.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/duplicate-subfolder/master/category.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/duplicate-tablename/bar.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/duplicate-tablename/foo.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/empty-folder/README.md +0 -1
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/invalid-export/plain.js +0 -3
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/invalid-schema/bad.js +0 -6
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/legacy-pattern/legacy.js +0 -12
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/multi-schema-distinct/audit/products.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/multi-schema-distinct/inventory/products.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/multi-schema-duplicate/a/products.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/multi-schema-duplicate/b/products.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/nested-deep/a/b/c/deep_table.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/.hidden/ignored.js +0 -7
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/master/category.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/master/supplier.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/transactions/stock_inbound.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/recursive-multi-folder/transactions/stock_inbound_item.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/valid-multiple/category.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/valid-multiple/item_product.js +0 -9
- package/generators/tests/unit/lib/dbschema-kit/fixtures/loader/valid-single/category.js +0 -8
- package/generators/tests/unit/lib/dbschema-kit/integration.test.js +0 -217
- package/generators/tests/unit/lib/dbschema-kit/introspect-mapper.test.js +0 -403
- package/generators/tests/unit/lib/dbschema-kit/ir-builder.test.js +0 -390
- package/generators/tests/unit/lib/dbschema-kit/loader.test.js +0 -128
- package/generators/tests/unit/lib/dbschema-kit/naming.test.js +0 -170
- package/generators/tests/unit/lib/dbschema-kit/parser/shorthand-parser.test.js +0 -237
- package/generators/tests/unit/lib/dbschema-kit/schema-printer.test.js +0 -251
- package/generators/tests/unit/lib/dbschema-kit/statement-modifier.test.js +0 -105
- package/generators/tests/unit/lib/dbschema-kit/statement-splitter.test.js +0 -165
- package/generators/tests/unit/lib/dbschema-kit/topological-sort.test.js +0 -135
- package/generators/tests/unit/lib/dbschema-kit/validator/check-compatibility-validator.test.js +0 -373
- package/generators/tests/unit/lib/dbschema-kit/validator/circular-relation-validator.test.js +0 -454
- package/generators/tests/unit/lib/dbschema-kit/validator/cross-model-validator.test.js +0 -512
- package/generators/tests/unit/lib/dbschema-kit/validator/enhanced-validate-integration.test.js +0 -390
- package/generators/tests/unit/lib/dbschema-kit/validator/naming-convention-validator.test.js +0 -306
- package/generators/tests/unit/lib/dbschema-kit/validator/schema-validator.test.js +0 -443
- package/generators/tests/unit/lib/dbschema-kit/validator/type-compatibility-validator.test.js +0 -440
- package/generators/tests/unit/lib/dbschema-kit/validator/validator-reporter.test.js +0 -172
- package/generators/tests/unit/lib/metadata-manager-dashboard.test.js +0 -256
- package/generators/tests/unit/lib/payload-validator-fieldpolicy.test.js +0 -240
- package/generators/tests/unit/lib/processor-validation-generator.test.js +0 -300
- package/generators/tests/unit/lib/sensitive-field-masker.test.js +0 -170
- package/generators/tests/unit/lib/sql-table-extractor.test.js +0 -119
- package/scripts/generate-integrity-manifest.js +0 -124
- package/scripts/snapshot-cli-contracts.js +0 -194
- package/scripts/verify-publish.js +0 -56
|
@@ -27,17 +27,21 @@ const path = require('path');
|
|
|
27
27
|
|
|
28
28
|
const { DatabaseIntrospector, loadDriver } = require('../utils/database-introspector');
|
|
29
29
|
const { resolveConfig, printDefaultConfigWarning } = require('../utils/config-resolver');
|
|
30
|
+
const {
|
|
31
|
+
DEFAULT_AUDIT_COLUMNS,
|
|
32
|
+
detectAuditAlignment
|
|
33
|
+
} = require('../utils/audit-columns');
|
|
34
|
+
const { compareSchemaStrict } = require('./schema-diff');
|
|
30
35
|
|
|
31
36
|
// Kolom audit yang di-handle otomatis oleh RESTForge runtime (base-model).
|
|
32
|
-
//
|
|
33
|
-
//
|
|
34
|
-
//
|
|
37
|
+
// Konstanta dipakai dari shared util agar source-of-truth tunggal lintas
|
|
38
|
+
// modul (sync, validate, endpoint create). Kolom ini di-exclude dari payload
|
|
39
|
+
// hasil generate karena nilainya selalu di-set runtime saat create/update.
|
|
35
40
|
//
|
|
36
41
|
// Bila tabel tidak memiliki satupun kolom dari list ini, generator otomatis
|
|
37
42
|
// menyertakan "auditColumns": false di payload supaya template generator
|
|
38
43
|
// men-set this.auditColumns = null di model. Tanpa flag ini, runtime akan
|
|
39
44
|
// mencoba inject kolom audit ke INSERT dan menyebabkan error 500.
|
|
40
|
-
const DEFAULT_EXCLUDED_COLUMNS = ['created_at', 'created_by', 'updated_at', 'updated_by'];
|
|
41
45
|
|
|
42
46
|
// Deteksi environment - Bun compiled binary atau Node.js/Bun script
|
|
43
47
|
const isBun = typeof Bun !== 'undefined';
|
|
@@ -461,6 +465,9 @@ class PayloadGenerator {
|
|
|
461
465
|
|
|
462
466
|
// Drift, error, atau target tidak ditemukan -> throw (exit 1 via cli-entry.js).
|
|
463
467
|
// Semantik "action required" untuk MCP/LSP integration.
|
|
468
|
+
// Marked silent karena verdict + summary sudah di-print oleh runValidate/
|
|
469
|
+
// runDiff/runSync; pesan "Error: Payload schema action required: ..."
|
|
470
|
+
// hanya menambah noise di stderr untuk human user.
|
|
464
471
|
const hasDrift = (result?.drift ?? 0) > 0;
|
|
465
472
|
const hasError = (result?.error ?? 0) > 0;
|
|
466
473
|
const targetMissing = targetTable && (result?.total ?? 0) === 0;
|
|
@@ -470,7 +477,10 @@ class PayloadGenerator {
|
|
|
470
477
|
if (hasDrift) reasons.push(`drift=${result.drift}`);
|
|
471
478
|
if (hasError) reasons.push(`error=${result.error}`);
|
|
472
479
|
if (targetMissing) reasons.push(`target '${targetTable}' not found`);
|
|
473
|
-
|
|
480
|
+
const err = new Error(`Payload schema action required: ${reasons.join(', ')}`);
|
|
481
|
+
err.silent = true;
|
|
482
|
+
err.exitCode = 1;
|
|
483
|
+
throw err;
|
|
474
484
|
}
|
|
475
485
|
|
|
476
486
|
return;
|
|
@@ -534,8 +544,8 @@ class PayloadGenerator {
|
|
|
534
544
|
const columns = await this.db.getColumns(args.table);
|
|
535
545
|
if (columns.length > 0) {
|
|
536
546
|
// Filter kolom audit yang di-handle otomatis oleh runtime.
|
|
537
|
-
const excludedPresent = columns.filter(col =>
|
|
538
|
-
payloadData.fieldName = columns.filter(col => !
|
|
547
|
+
const excludedPresent = columns.filter(col => DEFAULT_AUDIT_COLUMNS.includes(col));
|
|
548
|
+
payloadData.fieldName = columns.filter(col => !DEFAULT_AUDIT_COLUMNS.includes(col));
|
|
539
549
|
if (excludedPresent.length > 0) {
|
|
540
550
|
console.log(`Auto-managed columns excluded: ${excludedPresent.join(', ')}`);
|
|
541
551
|
} else {
|
|
@@ -639,86 +649,6 @@ class SchemaValidator {
|
|
|
639
649
|
this.outputDir = outputDir;
|
|
640
650
|
}
|
|
641
651
|
|
|
642
|
-
/**
|
|
643
|
-
* Normalisasi tipe data database ke kategori umum untuk perbandingan.
|
|
644
|
-
* Tipe database bervariasi antar engine, fungsi ini memetakan ke nama yang konsisten.
|
|
645
|
-
* @param {string} dataType - Tipe data dari information_schema
|
|
646
|
-
* @param {string} udtName - UDT name (PostgreSQL specific)
|
|
647
|
-
* @param {Object} col - Full column info object
|
|
648
|
-
* @returns {string} Normalized type string
|
|
649
|
-
*/
|
|
650
|
-
normalizeType(dataType, udtName, col) {
|
|
651
|
-
const dt = (dataType || '').toLowerCase();
|
|
652
|
-
const udt = (udtName || '').toLowerCase();
|
|
653
|
-
|
|
654
|
-
// UUID
|
|
655
|
-
if (dt === 'uuid' || udt === 'uuid') return 'uuid';
|
|
656
|
-
|
|
657
|
-
// Boolean
|
|
658
|
-
if (dt === 'boolean' || udt === 'bool') return 'boolean';
|
|
659
|
-
|
|
660
|
-
// Integer family
|
|
661
|
-
if (['integer', 'bigint', 'smallint', 'serial', 'bigserial', 'smallserial',
|
|
662
|
-
'int', 'tinyint', 'mediumint'].includes(dt) ||
|
|
663
|
-
['int4', 'int8', 'int2', 'serial4', 'serial8', 'serial2'].includes(udt)) {
|
|
664
|
-
return 'integer';
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
// Numeric/decimal family
|
|
668
|
-
if (['numeric', 'decimal', 'real', 'double precision', 'float', 'double'].includes(dt) ||
|
|
669
|
-
['numeric', 'float4', 'float8'].includes(udt)) {
|
|
670
|
-
const precision = col && col.numeric_precision ? `(${col.numeric_precision}` : '';
|
|
671
|
-
const scale = col && col.numeric_scale !== null && col.numeric_scale !== undefined
|
|
672
|
-
? `,${col.numeric_scale})` : precision ? ')' : '';
|
|
673
|
-
return precision ? `numeric${precision}${scale}` : 'numeric';
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
// Text / varchar family
|
|
677
|
-
if (['character varying', 'varchar', 'varchar2', 'nvarchar2', 'nvarchar'].includes(dt)) {
|
|
678
|
-
const len = col && col.character_maximum_length ? `(${col.character_maximum_length})` : '';
|
|
679
|
-
return `varchar${len}`;
|
|
680
|
-
}
|
|
681
|
-
if (['text', 'clob', 'nclob', 'longtext', 'mediumtext', 'tinytext'].includes(dt)) return 'text';
|
|
682
|
-
if (['char', 'character', 'nchar'].includes(dt)) {
|
|
683
|
-
const len = col && col.character_maximum_length ? `(${col.character_maximum_length})` : '';
|
|
684
|
-
return `char${len}`;
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
// Date/time family
|
|
688
|
-
if (dt === 'date') return 'date';
|
|
689
|
-
if (dt === 'datetime') return 'timestamp';
|
|
690
|
-
if (dt.startsWith('timestamp')) return 'timestamp';
|
|
691
|
-
if (dt.startsWith('time')) return 'time';
|
|
692
|
-
|
|
693
|
-
// JSON
|
|
694
|
-
if (['json', 'jsonb'].includes(dt) || ['json', 'jsonb'].includes(udt)) return 'json';
|
|
695
|
-
|
|
696
|
-
// Fallback
|
|
697
|
-
return dt || 'unknown';
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
/**
|
|
701
|
-
* Normalisasi tipe dari fieldValidation payload ke kategori yang sama.
|
|
702
|
-
* @param {Object} validation - Object dari array fieldValidation
|
|
703
|
-
* @returns {string} Normalized type string
|
|
704
|
-
*/
|
|
705
|
-
normalizePayloadValidationType(validation) {
|
|
706
|
-
if (!validation) return null;
|
|
707
|
-
const t = (validation.type || '').toLowerCase();
|
|
708
|
-
switch (t) {
|
|
709
|
-
case 'uuid': return 'uuid';
|
|
710
|
-
case 'integer': return 'integer';
|
|
711
|
-
case 'number': return 'numeric';
|
|
712
|
-
case 'boolean': return 'boolean';
|
|
713
|
-
case 'date': return 'date';
|
|
714
|
-
case 'datetime': return 'timestamp';
|
|
715
|
-
case 'string': return 'varchar';
|
|
716
|
-
case 'json':
|
|
717
|
-
case 'array': return 'json';
|
|
718
|
-
default: return t || null;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
|
|
722
652
|
/**
|
|
723
653
|
* Cari semua file payload JSON di outputDir.
|
|
724
654
|
* @returns {Array<{filePath: string, fileName: string, payload: Object}>}
|
|
@@ -781,120 +711,18 @@ class SchemaValidator {
|
|
|
781
711
|
return match || null;
|
|
782
712
|
}
|
|
783
713
|
|
|
784
|
-
/**
|
|
785
|
-
* Bandingkan satu payload dengan schema database aktual.
|
|
786
|
-
* @param {Object} payload - Payload JSON object
|
|
787
|
-
* @returns {Promise<Object>} Comparison result
|
|
788
|
-
*/
|
|
789
|
-
async comparePayloadWithDatabase(payload) {
|
|
790
|
-
const tableName = payload.tableName;
|
|
791
|
-
const result = {
|
|
792
|
-
tableName,
|
|
793
|
-
status: 'ok', // ok, drift, error
|
|
794
|
-
added: [], // kolom baru di database, tidak ada di payload
|
|
795
|
-
removed: [], // ada di payload, tidak ada di database
|
|
796
|
-
typeChanges: [], // tipe data berubah
|
|
797
|
-
nullabilityChanges: [], // nullable berubah
|
|
798
|
-
summary: ''
|
|
799
|
-
};
|
|
800
|
-
|
|
801
|
-
// Cek apakah table masih ada di database
|
|
802
|
-
const dbColumns = await this.db.getDetailedColumnInfo(tableName);
|
|
803
|
-
if (dbColumns.length === 0) {
|
|
804
|
-
result.status = 'error';
|
|
805
|
-
result.summary = `Table "${tableName}" not found in database`;
|
|
806
|
-
return result;
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
// Build map dari database columns
|
|
810
|
-
const dbColumnMap = {};
|
|
811
|
-
for (const col of dbColumns) {
|
|
812
|
-
dbColumnMap[col.column_name] = col;
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
// Build map dari payload fieldValidation
|
|
816
|
-
const payloadValidationMap = {};
|
|
817
|
-
if (payload.fieldValidation) {
|
|
818
|
-
for (const fv of payload.fieldValidation) {
|
|
819
|
-
payloadValidationMap[fv.name] = fv;
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
const payloadFields = payload.fieldName || [];
|
|
824
|
-
const dbColumnNames = dbColumns.map(c => c.column_name);
|
|
825
|
-
|
|
826
|
-
// Detect kolom baru di database (tidak ada di payload).
|
|
827
|
-
// Kolom audit default (DEFAULT_EXCLUDED_COLUMNS) yang tidak dicantumkan
|
|
828
|
-
// user di payload akan di-skip karena memang sengaja di-exclude.
|
|
829
|
-
for (const dbCol of dbColumns) {
|
|
830
|
-
if (!payloadFields.includes(dbCol.column_name)) {
|
|
831
|
-
if (DEFAULT_EXCLUDED_COLUMNS.includes(dbCol.column_name)) continue;
|
|
832
|
-
|
|
833
|
-
const normalizedType = this.normalizeType(dbCol.data_type, dbCol.udt_name, dbCol);
|
|
834
|
-
result.added.push({
|
|
835
|
-
column: dbCol.column_name,
|
|
836
|
-
type: normalizedType,
|
|
837
|
-
nullable: dbCol.is_nullable === 'YES'
|
|
838
|
-
});
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
// Detect kolom yang dihapus dari database (masih ada di payload)
|
|
843
|
-
for (const field of payloadFields) {
|
|
844
|
-
if (!dbColumnMap[field]) {
|
|
845
|
-
result.removed.push({
|
|
846
|
-
column: field
|
|
847
|
-
});
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
// Detect perubahan tipe data (hanya untuk field yang ada di kedua sisi)
|
|
852
|
-
for (const field of payloadFields) {
|
|
853
|
-
const dbCol = dbColumnMap[field];
|
|
854
|
-
if (!dbCol) continue;
|
|
855
|
-
|
|
856
|
-
const dbType = this.normalizeType(dbCol.data_type, dbCol.udt_name, dbCol);
|
|
857
|
-
const payloadValidation = payloadValidationMap[field];
|
|
858
|
-
|
|
859
|
-
if (payloadValidation) {
|
|
860
|
-
const payloadType = this.normalizePayloadValidationType(payloadValidation);
|
|
861
|
-
// Perbandingan menggunakan base type (tanpa size detail)
|
|
862
|
-
const dbBaseType = dbType.replace(/\(.*\)/, '');
|
|
863
|
-
const payloadBaseType = payloadType ? payloadType.replace(/\(.*\)/, '') : null;
|
|
864
|
-
|
|
865
|
-
if (payloadBaseType && dbBaseType !== payloadBaseType) {
|
|
866
|
-
result.typeChanges.push({
|
|
867
|
-
column: field,
|
|
868
|
-
payloadType: payloadType,
|
|
869
|
-
databaseType: dbType
|
|
870
|
-
});
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
// Determine overall status
|
|
876
|
-
if (result.added.length > 0 || result.removed.length > 0 || result.typeChanges.length > 0) {
|
|
877
|
-
result.status = 'drift';
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
// Build summary
|
|
881
|
-
const parts = [];
|
|
882
|
-
if (result.added.length > 0) parts.push(`${result.added.length} new column(s) in database`);
|
|
883
|
-
if (result.removed.length > 0) parts.push(`${result.removed.length} column(s) missing from database`);
|
|
884
|
-
if (result.typeChanges.length > 0) parts.push(`${result.typeChanges.length} type change(s)`);
|
|
885
|
-
result.summary = parts.length > 0 ? parts.join(', ') : 'Schema is in sync';
|
|
886
|
-
|
|
887
|
-
return result;
|
|
888
|
-
}
|
|
889
|
-
|
|
890
714
|
/**
|
|
891
715
|
* Format hasil perbandingan ke output console.
|
|
892
|
-
*
|
|
716
|
+
* Konsisten dengan `endpoint create` (audit-column-aware).
|
|
717
|
+
*
|
|
718
|
+
* @param {Object} comparison - Hasil dari compareSchemaStrict()
|
|
893
719
|
* @param {string} fileName - Nama file payload
|
|
894
|
-
* @param {boolean} showDiffDetail - Tampilkan detail
|
|
720
|
+
* @param {boolean} showDiffDetail - Tampilkan detail per-column drift
|
|
895
721
|
*/
|
|
896
722
|
printComparisonResult(comparison, fileName, showDiffDetail = false) {
|
|
897
|
-
|
|
723
|
+
// Pad status icon ke lebar tetap 7 char ([DRIFT]/[ERROR]) supaya kolom
|
|
724
|
+
// fileName tampil rata antar baris.
|
|
725
|
+
const statusIcon = comparison.status === 'ok' ? '[OK] '
|
|
898
726
|
: comparison.status === 'drift' ? '[DRIFT]'
|
|
899
727
|
: '[ERROR]';
|
|
900
728
|
|
|
@@ -915,24 +743,29 @@ class SchemaValidator {
|
|
|
915
743
|
// Status: drift
|
|
916
744
|
console.log(` ${comparison.summary}`);
|
|
917
745
|
|
|
918
|
-
if (showDiffDetail)
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
}
|
|
746
|
+
if (!showDiffDetail) return;
|
|
747
|
+
|
|
748
|
+
if (Array.isArray(comparison.removed)) {
|
|
749
|
+
for (const item of comparison.removed) {
|
|
750
|
+
console.log(` [-] ${item.column} (in payload, not in database)`);
|
|
924
751
|
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
}
|
|
752
|
+
}
|
|
753
|
+
if (Array.isArray(comparison.typeChanges)) {
|
|
754
|
+
for (const item of comparison.typeChanges) {
|
|
755
|
+
console.log(` [~] ${item.column} (type: ${item.payloadType} -> ${item.databaseType})`);
|
|
929
756
|
}
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
757
|
+
}
|
|
758
|
+
if (Array.isArray(comparison.added)) {
|
|
759
|
+
for (const item of comparison.added) {
|
|
760
|
+
const nullable = item.nullable ? ', nullable' : ', not null';
|
|
761
|
+
console.log(` [+] ${item.column} (${item.type}${nullable}) (in database, not in payload)`);
|
|
934
762
|
}
|
|
935
763
|
}
|
|
764
|
+
if (Array.isArray(comparison.auditMissing) && comparison.auditMissing.length > 0) {
|
|
765
|
+
const cols = comparison.auditMissing.join(', ');
|
|
766
|
+
console.log(` [+] ${cols}`);
|
|
767
|
+
console.log(' (required by auditColumns=true, not in database)');
|
|
768
|
+
}
|
|
936
769
|
}
|
|
937
770
|
|
|
938
771
|
/**
|
|
@@ -976,7 +809,7 @@ class SchemaValidator {
|
|
|
976
809
|
let ok = 0, drift = 0, error = 0;
|
|
977
810
|
|
|
978
811
|
for (const { fileName, payload } of payloads) {
|
|
979
|
-
const comparison = await this.
|
|
812
|
+
const comparison = await compareSchemaStrict(payload, this.db);
|
|
980
813
|
results.push({ fileName, comparison });
|
|
981
814
|
this.printComparisonResult(comparison, fileName, false);
|
|
982
815
|
|
|
@@ -1047,7 +880,7 @@ class SchemaValidator {
|
|
|
1047
880
|
console.log('-'.repeat(60));
|
|
1048
881
|
console.log();
|
|
1049
882
|
|
|
1050
|
-
const comparison = await this.
|
|
883
|
+
const comparison = await compareSchemaStrict(payload, this.db);
|
|
1051
884
|
results.push({ fileName, comparison });
|
|
1052
885
|
this.printComparisonResult(comparison, fileName, true);
|
|
1053
886
|
console.log();
|
|
@@ -1154,7 +987,7 @@ class SchemaValidator {
|
|
|
1154
987
|
let synced = 0, skipped = 0, errorCount = 0;
|
|
1155
988
|
|
|
1156
989
|
for (const { filePath, fileName, payload } of payloads) {
|
|
1157
|
-
const comparison = await this.
|
|
990
|
+
const comparison = await compareSchemaStrict(payload, this.db);
|
|
1158
991
|
|
|
1159
992
|
if (comparison.status === 'error') {
|
|
1160
993
|
console.log(` [ERROR] ${fileName} - ${comparison.summary}`);
|
|
@@ -1168,15 +1001,16 @@ class SchemaValidator {
|
|
|
1168
1001
|
continue;
|
|
1169
1002
|
}
|
|
1170
1003
|
|
|
1171
|
-
// Status: drift
|
|
1172
|
-
// 1. Archive file lama
|
|
1004
|
+
// Status: drift (termasuk audit drift) — archive + regenerate.
|
|
1173
1005
|
const archivePath = this.archiveFile(filePath);
|
|
1174
1006
|
const archiveName = path.basename(archivePath);
|
|
1175
1007
|
console.log(` [ARCHIVE] ${fileName} -> ${archiveName}`);
|
|
1176
1008
|
|
|
1177
|
-
//
|
|
1009
|
+
// Re-generate payload dari database. regeneratePayload menerapkan audit
|
|
1010
|
+
// columns resolution secara internal (set auditColumns: false bila DB
|
|
1011
|
+
// tidak punya kolom audit standar).
|
|
1178
1012
|
try {
|
|
1179
|
-
const updatedPayload = await this.regeneratePayload(payload, comparison);
|
|
1013
|
+
const updatedPayload = await this.regeneratePayload(payload, comparison, { fileName });
|
|
1180
1014
|
fs.writeFileSync(filePath, JSON.stringify(updatedPayload, null, 4), 'utf8');
|
|
1181
1015
|
console.log(` [SYNCED] ${fileName} - ${comparison.summary}`);
|
|
1182
1016
|
synced++;
|
|
@@ -1205,12 +1039,17 @@ class SchemaValidator {
|
|
|
1205
1039
|
/**
|
|
1206
1040
|
* Regenerate payload berdasarkan perubahan yang terdeteksi.
|
|
1207
1041
|
* Mempertahankan konfigurasi payload lama (action, filters, dll),
|
|
1208
|
-
* hanya update fieldName, fieldValidation, dateTimeFields, dan
|
|
1042
|
+
* hanya update fieldName, fieldValidation, dateTimeFields, query, dan
|
|
1043
|
+
* (sejak Phase 03) field `auditColumns` bila terjadi misalignment dengan
|
|
1044
|
+
* tabel database.
|
|
1045
|
+
*
|
|
1209
1046
|
* @param {Object} oldPayload - Payload JSON lama
|
|
1210
1047
|
* @param {Object} comparison - Hasil comparePayloadWithDatabase
|
|
1048
|
+
* @param {Object} [options]
|
|
1049
|
+
* @param {string} [options.fileName] - Nama file payload untuk pesan log
|
|
1211
1050
|
* @returns {Promise<Object>} Updated payload
|
|
1212
1051
|
*/
|
|
1213
|
-
async regeneratePayload(oldPayload, comparison) {
|
|
1052
|
+
async regeneratePayload(oldPayload, comparison, options = {}) {
|
|
1214
1053
|
const tableName = oldPayload.tableName;
|
|
1215
1054
|
|
|
1216
1055
|
// Ambil data terbaru dari database
|
|
@@ -1233,7 +1072,7 @@ class SchemaValidator {
|
|
|
1233
1072
|
// Tambahkan field baru dari database, skip kolom audit default
|
|
1234
1073
|
for (const col of dbColumns) {
|
|
1235
1074
|
if (newFieldName.includes(col)) continue;
|
|
1236
|
-
if (
|
|
1075
|
+
if (DEFAULT_AUDIT_COLUMNS.includes(col)) continue;
|
|
1237
1076
|
newFieldName.push(col);
|
|
1238
1077
|
}
|
|
1239
1078
|
|
|
@@ -1291,8 +1130,86 @@ class SchemaValidator {
|
|
|
1291
1130
|
delete updatedPayload.fieldValidation;
|
|
1292
1131
|
}
|
|
1293
1132
|
|
|
1133
|
+
// Audit columns resolution (Phase 03):
|
|
1134
|
+
// Pastikan field `auditColumns` di payload aligned dengan struktur tabel
|
|
1135
|
+
// database. Logic ini mencegah inkonsistensi antara `payload sync` (yang
|
|
1136
|
+
// sebelumnya tidak menyentuh auditColumns) dan `endpoint create` (yang
|
|
1137
|
+
// sudah audit-column-aware sejak Phase 01).
|
|
1138
|
+
this.resolveAuditColumnsForSync(updatedPayload, oldPayload, dbColumns, {
|
|
1139
|
+
tableName,
|
|
1140
|
+
fileName: options.fileName
|
|
1141
|
+
});
|
|
1142
|
+
|
|
1294
1143
|
return updatedPayload;
|
|
1295
1144
|
}
|
|
1145
|
+
|
|
1146
|
+
/**
|
|
1147
|
+
* Resolve nilai `auditColumns` untuk payload hasil sync. Memutasi
|
|
1148
|
+
* `updatedPayload` in-place.
|
|
1149
|
+
*
|
|
1150
|
+
* Aturan (lihat phase-03-audit-aware-sync.md):
|
|
1151
|
+
* - oldPayload.auditColumns === false/null -> preserve (no-op)
|
|
1152
|
+
* - oldPayload.auditColumns object form -> warn, no auto-override
|
|
1153
|
+
* - oldPayload.auditColumns === true + DB tidak full audit -> override
|
|
1154
|
+
* ke false + warning ke stderr
|
|
1155
|
+
* - oldPayload.auditColumns tidak di-set (default true) + DB tidak full
|
|
1156
|
+
* audit -> set false + info message
|
|
1157
|
+
* - DB punya keempat kolom audit standar -> preserve apapun bentuknya
|
|
1158
|
+
*
|
|
1159
|
+
* "DB tidak full audit" mencakup `none` (tidak satupun kolom audit) dan
|
|
1160
|
+
* `partial` (1-3 kolom audit). Partial di-treat sebagai incomplete: shape
|
|
1161
|
+
* audit tidak lengkap, generator tidak bisa inject 4 kolom sambil sebagian
|
|
1162
|
+
* tidak exist. Default strict yang aman.
|
|
1163
|
+
*
|
|
1164
|
+
* @param {Object} updatedPayload - Payload yang akan ditulis (mutated)
|
|
1165
|
+
* @param {Object} oldPayload - Payload lama (untuk inspect state asli)
|
|
1166
|
+
* @param {string[]} dbColumns - Daftar kolom database
|
|
1167
|
+
* @param {Object} ctx
|
|
1168
|
+
* @param {string} ctx.tableName - Nama table
|
|
1169
|
+
* @param {string} [ctx.fileName] - Nama file payload untuk pesan log
|
|
1170
|
+
* @returns {void}
|
|
1171
|
+
*/
|
|
1172
|
+
resolveAuditColumnsForSync(updatedPayload, oldPayload, dbColumns, ctx) {
|
|
1173
|
+
const tableName = ctx.tableName;
|
|
1174
|
+
const fileLabel = ctx.fileName || `${tableName}.json`;
|
|
1175
|
+
const alignment = detectAuditAlignment(dbColumns);
|
|
1176
|
+
const hasField = Object.prototype.hasOwnProperty.call(oldPayload, 'auditColumns');
|
|
1177
|
+
const value = hasField ? oldPayload.auditColumns : undefined;
|
|
1178
|
+
|
|
1179
|
+
// Case 1: explicit false/null -> preserve (no-op)
|
|
1180
|
+
if (value === false || value === null) {
|
|
1181
|
+
return;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
// Case 2: object form (custom column mapping) -> warn, no auto-override
|
|
1185
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
1186
|
+
console.warn(
|
|
1187
|
+
`[restforge] Custom auditColumns object detected for "${tableName}". ` +
|
|
1188
|
+
'Cannot auto-resolve. Verify column names manually.'
|
|
1189
|
+
);
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
// Case 3: DB punya semua kolom audit -> preserve apa adanya
|
|
1194
|
+
if (alignment.all) {
|
|
1195
|
+
return;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
// Case 4: DB tidak full audit (none atau partial) + payload default/true
|
|
1199
|
+
// -> set updatedPayload.auditColumns = false
|
|
1200
|
+
if (value === true) {
|
|
1201
|
+
console.warn(
|
|
1202
|
+
`[restforge] Resetting auditColumns: true -> false for table "${tableName}" ` +
|
|
1203
|
+
'because audit columns missing in database'
|
|
1204
|
+
);
|
|
1205
|
+
} else {
|
|
1206
|
+
console.log(
|
|
1207
|
+
`[restforge] Set "auditColumns": false in ${fileLabel} ` +
|
|
1208
|
+
'because audit columns missing in database'
|
|
1209
|
+
);
|
|
1210
|
+
}
|
|
1211
|
+
updatedPayload.auditColumns = false;
|
|
1212
|
+
}
|
|
1296
1213
|
}
|
|
1297
1214
|
|
|
1298
1215
|
module.exports = {
|