@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
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
const test = require('node:test');
|
|
2
|
-
const assert = require('node:assert');
|
|
3
|
-
const fs = require('node:fs');
|
|
4
|
-
const path = require('node:path');
|
|
5
|
-
const os = require('node:os');
|
|
6
|
-
const { spawnSync } = require('node:child_process');
|
|
7
|
-
|
|
8
|
-
const REPO_ROOT = path.resolve(__dirname, '..', '..', '..');
|
|
9
|
-
const CLI_SCRIPT = path.join(REPO_ROOT, 'cli', 'create-processor.js');
|
|
10
|
-
const FIXTURES_DIR = path.join(REPO_ROOT, 'tests', 'fixtures', 'payloads');
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Siapkan temp workspace dengan payload fixture, lalu jalankan generator.
|
|
14
|
-
* Returns { workDir, routerPath, processorDir, exitCode, stdout, stderr }.
|
|
15
|
-
*/
|
|
16
|
-
function runGenerator({ fixtureName, project, endpoint, extraArgs = [] }) {
|
|
17
|
-
const workDir = fs.mkdtempSync(path.join(os.tmpdir(), 'rf-cli-test-'));
|
|
18
|
-
const payloadDir = path.join(workDir, 'payload');
|
|
19
|
-
fs.mkdirSync(payloadDir, { recursive: true });
|
|
20
|
-
fs.copyFileSync(path.join(FIXTURES_DIR, fixtureName), path.join(payloadDir, fixtureName));
|
|
21
|
-
|
|
22
|
-
const result = spawnSync(process.execPath, [
|
|
23
|
-
CLI_SCRIPT,
|
|
24
|
-
`--project=${project}`,
|
|
25
|
-
`--endpoint=${endpoint}`,
|
|
26
|
-
`--payload=${fixtureName}`,
|
|
27
|
-
...extraArgs
|
|
28
|
-
], {
|
|
29
|
-
cwd: workDir,
|
|
30
|
-
encoding: 'utf-8',
|
|
31
|
-
env: { ...process.env, NODE_ENV: 'test' }
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const routerPath = path.join(workDir, 'src', 'modules', project, `${endpoint}.js`);
|
|
35
|
-
const processorDir = path.join(workDir, 'src', 'modules', project, 'processor', endpoint);
|
|
36
|
-
|
|
37
|
-
return {
|
|
38
|
-
workDir,
|
|
39
|
-
routerPath,
|
|
40
|
-
processorDir,
|
|
41
|
-
exitCode: result.status,
|
|
42
|
-
stdout: result.stdout,
|
|
43
|
-
stderr: result.stderr
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function cleanup(workDir) {
|
|
48
|
-
try {
|
|
49
|
-
fs.rmSync(workDir, { recursive: true, force: true });
|
|
50
|
-
} catch (err) {
|
|
51
|
-
// Best-effort cleanup saja.
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
test('router berisi SECURITY banner, validation block, dan masker helper', () => {
|
|
56
|
-
const run = runGenerator({
|
|
57
|
-
fixtureName: 'order-process.json',
|
|
58
|
-
project: 'sales',
|
|
59
|
-
endpoint: 'order-process'
|
|
60
|
-
});
|
|
61
|
-
try {
|
|
62
|
-
assert.strictEqual(run.exitCode, 0, `Generator exit with non-zero: ${run.stderr}`);
|
|
63
|
-
const router = fs.readFileSync(run.routerPath, 'utf-8');
|
|
64
|
-
|
|
65
|
-
// Banner SECURITY di atas route handler.
|
|
66
|
-
assert.match(router, /SECURITY: Validation di-enforce di router layer/);
|
|
67
|
-
assert.match(router, /JANGAN edit file router ini/);
|
|
68
|
-
|
|
69
|
-
// Masker helper di-inject.
|
|
70
|
-
assert.match(router, /SENSITIVE_FIELD_PATTERNS/);
|
|
71
|
-
assert.match(router, /function __maskSensitive/);
|
|
72
|
-
|
|
73
|
-
// Validation block menggunakan __validationErrors.
|
|
74
|
-
assert.match(router, /const __validationErrors = \[\];/);
|
|
75
|
-
assert.match(router, /'Field "so_id" wajib diisi'/);
|
|
76
|
-
assert.match(router, /harus berupa UUID yang valid/);
|
|
77
|
-
|
|
78
|
-
// Header mapping dengan type check.
|
|
79
|
-
assert.match(router, /typeof req\.headers\['x-app-code'\] === 'string'/);
|
|
80
|
-
|
|
81
|
-
// Enum whitelist untuk decision field.
|
|
82
|
-
assert.match(router, /\['approve', 'partial-approve'\]\.includes/);
|
|
83
|
-
|
|
84
|
-
// Debug log dibungkus NODE_ENV guard dan pakai __maskSensitive.
|
|
85
|
-
assert.match(router, /NODE_ENV !== 'production'/);
|
|
86
|
-
assert.match(router, /__maskSensitive\(input\)/);
|
|
87
|
-
|
|
88
|
-
// Error handler hanya pakai error.message (bukan full error).
|
|
89
|
-
assert.match(router, /console\.error\([^)]*error\.message\)/);
|
|
90
|
-
|
|
91
|
-
// Sintaks valid.
|
|
92
|
-
assert.doesNotThrow(() => new Function(fs.readFileSync(run.routerPath, 'utf-8')));
|
|
93
|
-
} finally {
|
|
94
|
-
cleanup(run.workDir);
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
test('processor scaffold berisi SECURITY BOUNDARY docstring dan inline warning', () => {
|
|
99
|
-
const run = runGenerator({
|
|
100
|
-
fixtureName: 'order-process.json',
|
|
101
|
-
project: 'sales',
|
|
102
|
-
endpoint: 'order-process'
|
|
103
|
-
});
|
|
104
|
-
try {
|
|
105
|
-
assert.strictEqual(run.exitCode, 0);
|
|
106
|
-
const scaffold = fs.readFileSync(path.join(run.processorDir, 'submit-order.js'), 'utf-8');
|
|
107
|
-
|
|
108
|
-
assert.match(scaffold, /SECURITY BOUNDARY \(jangan dilemahkan saat refactor\)/);
|
|
109
|
-
assert.match(scaffold, /parameterized placeholder/);
|
|
110
|
-
assert.match(scaffold, /Concat user input ke SQL string DILARANG/);
|
|
111
|
-
assert.match(scaffold, /Identifier dinamis \(kolom\/tabel\) WAJIB di-whitelist/);
|
|
112
|
-
assert.match(scaffold, /Field sensitif .+ JANGAN di-log plaintext/);
|
|
113
|
-
|
|
114
|
-
// Inline warning sebelum db.executeQuery.
|
|
115
|
-
assert.match(scaffold, /SECURITY: SQL executed dengan parameterized placeholder/);
|
|
116
|
-
assert.match(scaffold, /paramCount/);
|
|
117
|
-
|
|
118
|
-
// Sintaks valid.
|
|
119
|
-
assert.doesNotThrow(() => new Function(scaffold));
|
|
120
|
-
} finally {
|
|
121
|
-
cleanup(run.workDir);
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
test('payload dengan password field: router auto-mask via default pattern', () => {
|
|
126
|
-
const run = runGenerator({
|
|
127
|
-
fixtureName: 'login-with-password.json',
|
|
128
|
-
project: 'auth',
|
|
129
|
-
endpoint: 'session'
|
|
130
|
-
});
|
|
131
|
-
try {
|
|
132
|
-
assert.strictEqual(run.exitCode, 0);
|
|
133
|
-
const router = fs.readFileSync(run.routerPath, 'utf-8');
|
|
134
|
-
|
|
135
|
-
// Masker helper di-inject dengan pattern default.
|
|
136
|
-
assert.match(router, /SENSITIVE_FIELD_PATTERNS = \/\^\(password\|/);
|
|
137
|
-
|
|
138
|
-
// Eksekusi helper dari kode router untuk verifikasi runtime mask.
|
|
139
|
-
const helperCode = router.match(/const SENSITIVE_FIELD_PATTERNS[\s\S]+?^}/m)[0];
|
|
140
|
-
const runner = new Function(`${helperCode}\nreturn __maskSensitive(arguments[0]);`);
|
|
141
|
-
const masked = runner({ username: 'ibrahim', password: 'secret123' });
|
|
142
|
-
assert.strictEqual(masked.password, '***MASKED***');
|
|
143
|
-
assert.strictEqual(masked.username, 'ibrahim');
|
|
144
|
-
} finally {
|
|
145
|
-
cleanup(run.workDir);
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
test('payload dengan request.validate:false: router emit komentar opt-out saja', () => {
|
|
150
|
-
const run = runGenerator({
|
|
151
|
-
fixtureName: 'dynamic-search-optout.json',
|
|
152
|
-
project: 'contact',
|
|
153
|
-
endpoint: 'search'
|
|
154
|
-
});
|
|
155
|
-
try {
|
|
156
|
-
assert.strictEqual(run.exitCode, 0);
|
|
157
|
-
const router = fs.readFileSync(run.routerPath, 'utf-8');
|
|
158
|
-
|
|
159
|
-
assert.match(router, /Router validation di-opt-out via "request\.validate": false/);
|
|
160
|
-
// Tidak ada __validationErrors di router yang opt-out.
|
|
161
|
-
assert.doesNotMatch(router, /__validationErrors/);
|
|
162
|
-
} finally {
|
|
163
|
-
cleanup(run.workDir);
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
test('custom sensitive keyword: safe keyword masuk regex, keyword berbahaya di-filter', () => {
|
|
168
|
-
const run = runGenerator({
|
|
169
|
-
fixtureName: 'custom-sensitive.json',
|
|
170
|
-
project: 'auth',
|
|
171
|
-
endpoint: 'signup'
|
|
172
|
-
});
|
|
173
|
-
try {
|
|
174
|
-
assert.strictEqual(run.exitCode, 0);
|
|
175
|
-
const router = fs.readFileSync(run.routerPath, 'utf-8');
|
|
176
|
-
|
|
177
|
-
// Keyword "ktp_number" dan "npwp" adalah identifier aman -> masuk pattern.
|
|
178
|
-
assert.match(router, /ktp_number/);
|
|
179
|
-
assert.match(router, /npwp/);
|
|
180
|
-
|
|
181
|
-
// Keyword dengan meta character regex ('.*', '|') harus di-filter.
|
|
182
|
-
const patternLine = router.split('\n').find((l) => l.includes('SENSITIVE_FIELD_PATTERNS'));
|
|
183
|
-
assert.ok(patternLine, 'Pattern line harus ada');
|
|
184
|
-
assert.ok(!patternLine.includes('attack_name.*'), 'Keyword berbahaya attack_name.* tidak boleh masuk regex');
|
|
185
|
-
assert.ok(!patternLine.includes('another|field'), 'Keyword berbahaya another|field tidak boleh masuk regex');
|
|
186
|
-
} finally {
|
|
187
|
-
cleanup(run.workDir);
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
test('regenerate tanpa --force: processor scaffold yang sudah ada tidak di-overwrite', () => {
|
|
192
|
-
const run = runGenerator({
|
|
193
|
-
fixtureName: 'order-process.json',
|
|
194
|
-
project: 'sales',
|
|
195
|
-
endpoint: 'order-process'
|
|
196
|
-
});
|
|
197
|
-
try {
|
|
198
|
-
assert.strictEqual(run.exitCode, 0);
|
|
199
|
-
const scaffoldPath = path.join(run.processorDir, 'submit-order.js');
|
|
200
|
-
|
|
201
|
-
// Inject custom marker ke scaffold existing.
|
|
202
|
-
const customContent = fs.readFileSync(scaffoldPath, 'utf-8') + '\n// CUSTOM_CODE_MARKER';
|
|
203
|
-
fs.writeFileSync(scaffoldPath, customContent);
|
|
204
|
-
|
|
205
|
-
// Re-run generator tanpa --force.
|
|
206
|
-
const rerun = spawnSync(process.execPath, [
|
|
207
|
-
CLI_SCRIPT,
|
|
208
|
-
'--project=sales',
|
|
209
|
-
'--endpoint=order-process',
|
|
210
|
-
'--payload=order-process.json'
|
|
211
|
-
], {
|
|
212
|
-
cwd: run.workDir,
|
|
213
|
-
encoding: 'utf-8',
|
|
214
|
-
env: { ...process.env, NODE_ENV: 'test' }
|
|
215
|
-
});
|
|
216
|
-
assert.strictEqual(rerun.status, 0, `Re-run exit with non-zero: ${rerun.stderr}`);
|
|
217
|
-
|
|
218
|
-
const preservedContent = fs.readFileSync(scaffoldPath, 'utf-8');
|
|
219
|
-
assert.match(preservedContent, /CUSTOM_CODE_MARKER/, 'Custom code harus tetap ada (skip-if-exists)');
|
|
220
|
-
} finally {
|
|
221
|
-
cleanup(run.workDir);
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
test('attack vector: router menolak body tanpa required field (HTTP 400)', () => {
|
|
226
|
-
const run = runGenerator({
|
|
227
|
-
fixtureName: 'order-process.json',
|
|
228
|
-
project: 'sales',
|
|
229
|
-
endpoint: 'order-process'
|
|
230
|
-
});
|
|
231
|
-
try {
|
|
232
|
-
assert.strictEqual(run.exitCode, 0);
|
|
233
|
-
const router = fs.readFileSync(run.routerPath, 'utf-8');
|
|
234
|
-
|
|
235
|
-
// Extract blok validation untuk submit-order dan eksekusi manual.
|
|
236
|
-
// Cari chain validation di antara header mapping dan debug log.
|
|
237
|
-
const match = router.match(/const __validationErrors = \[\];[\s\S]+?if \(__validationErrors\.length[\s\S]+?\}\s*\n/);
|
|
238
|
-
assert.ok(match, 'Validation block harus ada di router');
|
|
239
|
-
|
|
240
|
-
const resObj = {
|
|
241
|
-
__status: 0, __payload: null,
|
|
242
|
-
status(c) { this.__status = c; return this; },
|
|
243
|
-
json(b) { this.__payload = b; return this; }
|
|
244
|
-
};
|
|
245
|
-
const fn = new Function('input', 'res', match[0]);
|
|
246
|
-
|
|
247
|
-
// Body kosong -> required so_id dan app_code hilang.
|
|
248
|
-
fn({}, resObj);
|
|
249
|
-
assert.strictEqual(resObj.__status, 400);
|
|
250
|
-
assert.ok(Array.isArray(resObj.__payload.errors));
|
|
251
|
-
const fields = resObj.__payload.errors.map(e => e.field);
|
|
252
|
-
assert.ok(fields.includes('so_id'), 'Errors harus mention so_id');
|
|
253
|
-
assert.ok(fields.includes('app_code'), 'Errors harus mention app_code');
|
|
254
|
-
} finally {
|
|
255
|
-
cleanup(run.workDir);
|
|
256
|
-
}
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
test('attack vector: UUID injection payload ter-reject di router', () => {
|
|
260
|
-
const run = runGenerator({
|
|
261
|
-
fixtureName: 'order-process.json',
|
|
262
|
-
project: 'sales',
|
|
263
|
-
endpoint: 'order-process'
|
|
264
|
-
});
|
|
265
|
-
try {
|
|
266
|
-
assert.strictEqual(run.exitCode, 0);
|
|
267
|
-
const router = fs.readFileSync(run.routerPath, 'utf-8');
|
|
268
|
-
const match = router.match(/const __validationErrors = \[\];[\s\S]+?if \(__validationErrors\.length[\s\S]+?\}\s*\n/);
|
|
269
|
-
|
|
270
|
-
const resObj = {
|
|
271
|
-
__status: 0, __payload: null,
|
|
272
|
-
status(c) { this.__status = c; return this; },
|
|
273
|
-
json(b) { this.__payload = b; return this; }
|
|
274
|
-
};
|
|
275
|
-
const fn = new Function('input', 'res', match[0]);
|
|
276
|
-
|
|
277
|
-
// Payload serangan: so_id berisi SQL injection, bukan UUID.
|
|
278
|
-
fn({
|
|
279
|
-
so_id: "'; DROP TABLE sales_order; --",
|
|
280
|
-
app_code: 'sales-app'
|
|
281
|
-
}, resObj);
|
|
282
|
-
assert.strictEqual(resObj.__status, 400);
|
|
283
|
-
const uuidError = resObj.__payload.errors.find(e => e.field === 'so_id');
|
|
284
|
-
assert.ok(uuidError, 'so_id harus ada di errors');
|
|
285
|
-
assert.match(uuidError.message, /UUID yang valid/);
|
|
286
|
-
} finally {
|
|
287
|
-
cleanup(run.workDir);
|
|
288
|
-
}
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
test('payload invalid: generator reject dan exit non-zero', () => {
|
|
292
|
-
const workDir = fs.mkdtempSync(path.join(os.tmpdir(), 'rf-cli-test-'));
|
|
293
|
-
const payloadDir = path.join(workDir, 'payload');
|
|
294
|
-
fs.mkdirSync(payloadDir, { recursive: true });
|
|
295
|
-
|
|
296
|
-
// Payload dengan sensitive flag berisi non-boolean (reject di validator).
|
|
297
|
-
const bad = {
|
|
298
|
-
processor: [{
|
|
299
|
-
name: 'bad',
|
|
300
|
-
method: 'POST',
|
|
301
|
-
request: { body: { x: { type: 'string', sensitive: 'yes' } } }
|
|
302
|
-
}]
|
|
303
|
-
};
|
|
304
|
-
fs.writeFileSync(path.join(payloadDir, 'bad.json'), JSON.stringify(bad));
|
|
305
|
-
|
|
306
|
-
const result = spawnSync(process.execPath, [
|
|
307
|
-
CLI_SCRIPT,
|
|
308
|
-
'--project=test',
|
|
309
|
-
'--endpoint=bad',
|
|
310
|
-
'--payload=bad.json'
|
|
311
|
-
], { cwd: workDir, encoding: 'utf-8', env: { ...process.env, NODE_ENV: 'test' } });
|
|
312
|
-
|
|
313
|
-
try {
|
|
314
|
-
assert.notStrictEqual(result.status, 0);
|
|
315
|
-
assert.match(result.stdout + result.stderr, /sensitive/);
|
|
316
|
-
} finally {
|
|
317
|
-
cleanup(workDir);
|
|
318
|
-
}
|
|
319
|
-
});
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const test = require('node:test');
|
|
4
|
-
const assert = require('node:assert');
|
|
5
|
-
const fs = require('node:fs');
|
|
6
|
-
const path = require('node:path');
|
|
7
|
-
const os = require('node:os');
|
|
8
|
-
const { spawnSync } = require('node:child_process');
|
|
9
|
-
|
|
10
|
-
const REPO_ROOT = path.resolve(__dirname, '..', '..', '..');
|
|
11
|
-
const CLI_ENTRY = path.join(REPO_ROOT, 'restforge-cli.js');
|
|
12
|
-
|
|
13
|
-
const SAMPLE_PAYLOAD_PATH = path.resolve(
|
|
14
|
-
REPO_ROOT,
|
|
15
|
-
'..',
|
|
16
|
-
'restforge',
|
|
17
|
-
'docs',
|
|
18
|
-
'architecture',
|
|
19
|
-
'dashboard-architecture',
|
|
20
|
-
'payload',
|
|
21
|
-
'dashboard-sales.json'
|
|
22
|
-
);
|
|
23
|
-
const SAMPLE_PAYLOAD_DIR = path.dirname(SAMPLE_PAYLOAD_PATH);
|
|
24
|
-
const SAMPLE_QUERY_DIR = path.join(SAMPLE_PAYLOAD_DIR, 'query');
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Buat tmp working dir lengkap dengan payload dashboard sample plus
|
|
28
|
-
* file SQL referensi. Direplikasi dari create-dashboard.test.js agar
|
|
29
|
-
* dispatch test self-contained dan tidak bergantung helper eksternal.
|
|
30
|
-
*/
|
|
31
|
-
function setupTmpProject() {
|
|
32
|
-
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'rf-dash-disp-'));
|
|
33
|
-
const tmpPayloadDir = path.join(tmpDir, 'payload');
|
|
34
|
-
const tmpQueryDir = path.join(tmpPayloadDir, 'query');
|
|
35
|
-
fs.mkdirSync(tmpQueryDir, { recursive: true });
|
|
36
|
-
|
|
37
|
-
fs.copyFileSync(
|
|
38
|
-
SAMPLE_PAYLOAD_PATH,
|
|
39
|
-
path.join(tmpPayloadDir, 'dashboard-sales.json')
|
|
40
|
-
);
|
|
41
|
-
for (const sqlFile of fs.readdirSync(SAMPLE_QUERY_DIR)) {
|
|
42
|
-
fs.copyFileSync(
|
|
43
|
-
path.join(SAMPLE_QUERY_DIR, sqlFile),
|
|
44
|
-
path.join(tmpQueryDir, sqlFile)
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return tmpDir;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function cleanupTmpProject(tmpDir) {
|
|
52
|
-
try {
|
|
53
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
54
|
-
} catch (err) {
|
|
55
|
-
// Best-effort cleanup.
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function runEntry(args, cwd) {
|
|
60
|
-
return spawnSync(process.execPath, [CLI_ENTRY, ...args], {
|
|
61
|
-
cwd: cwd || REPO_ROOT,
|
|
62
|
-
encoding: 'utf-8',
|
|
63
|
-
env: { ...process.env, NODE_ENV: 'test' }
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// ===== Help routing =====
|
|
68
|
-
|
|
69
|
-
test('help global menampilkan command dashboard di section Project Generation', () => {
|
|
70
|
-
const result = runEntry(['--help']);
|
|
71
|
-
assert.strictEqual(result.status, 0, `exit non-zero: ${result.stderr}`);
|
|
72
|
-
const out = result.stdout;
|
|
73
|
-
assert.match(out, /Project Generation:/);
|
|
74
|
-
assert.match(
|
|
75
|
-
out,
|
|
76
|
-
/dashboard\s+Generate dashboard endpoint module/,
|
|
77
|
-
'baris dashboard harus tercantum di section Project Generation'
|
|
78
|
-
);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
test('dispatch dashboard --help: showHelp dari create-dashboard.js terpanggil', () => {
|
|
82
|
-
const result = runEntry(['dashboard', '--help']);
|
|
83
|
-
assert.strictEqual(result.status, 0, `exit non-zero: ${result.stderr}`);
|
|
84
|
-
const out = result.stdout;
|
|
85
|
-
assert.match(
|
|
86
|
-
out,
|
|
87
|
-
/Create Dashboard Tool - Help/,
|
|
88
|
-
'showHelp() create-dashboard harus muncul (marker banner)'
|
|
89
|
-
);
|
|
90
|
-
assert.match(
|
|
91
|
-
out,
|
|
92
|
-
/Dashboard name \(REQUIRED\)/,
|
|
93
|
-
'showHelp() create-dashboard harus mencantumkan opsi --name'
|
|
94
|
-
);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
test('alias dash di-resolve ke dashboard (dash --help sama dengan dashboard --help)', () => {
|
|
98
|
-
const aliasResult = runEntry(['dash', '--help']);
|
|
99
|
-
assert.strictEqual(aliasResult.status, 0, `alias exit non-zero: ${aliasResult.stderr}`);
|
|
100
|
-
assert.match(
|
|
101
|
-
aliasResult.stdout,
|
|
102
|
-
/Create Dashboard Tool - Help/,
|
|
103
|
-
'alias dash harus dispatch ke create-dashboard showHelp'
|
|
104
|
-
);
|
|
105
|
-
assert.match(
|
|
106
|
-
aliasResult.stdout,
|
|
107
|
-
/Dashboard name \(REQUIRED\)/,
|
|
108
|
-
'alias dash harus tampilkan opsi --name dari create-dashboard showHelp'
|
|
109
|
-
);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
// ===== Dispatch happy path =====
|
|
113
|
-
|
|
114
|
-
test('dispatch happy path: dashboard via entry point menghasilkan dash module di tmp dir', () => {
|
|
115
|
-
const tmpDir = setupTmpProject();
|
|
116
|
-
try {
|
|
117
|
-
const result = runEntry([
|
|
118
|
-
'dashboard',
|
|
119
|
-
'--project=mini-inventory',
|
|
120
|
-
'--name=dash-sales',
|
|
121
|
-
'--payload=dashboard-sales'
|
|
122
|
-
], tmpDir);
|
|
123
|
-
|
|
124
|
-
assert.strictEqual(result.status, 0, `dispatch exit non-zero: ${result.stderr}`);
|
|
125
|
-
|
|
126
|
-
const dashModulePath = path.join(
|
|
127
|
-
tmpDir, 'src', 'modules', 'mini-inventory', 'dash-sales.js'
|
|
128
|
-
);
|
|
129
|
-
assert.strictEqual(
|
|
130
|
-
fs.existsSync(dashModulePath),
|
|
131
|
-
true,
|
|
132
|
-
'dispatch via entry point harus menghasilkan dash-sales.js di tmp dir'
|
|
133
|
-
);
|
|
134
|
-
} finally {
|
|
135
|
-
cleanupTmpProject(tmpDir);
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
// ===== Regresi: unknown command =====
|
|
140
|
-
|
|
141
|
-
test('unknown command tetap exit 1 dan stderr menyebut Unknown command', () => {
|
|
142
|
-
const result = runEntry(['unknown-cmd']);
|
|
143
|
-
assert.notStrictEqual(result.status, 0);
|
|
144
|
-
assert.match(
|
|
145
|
-
result.stderr,
|
|
146
|
-
/Unknown command/,
|
|
147
|
-
'stderr harus menyebut Unknown command saat command tidak dikenal'
|
|
148
|
-
);
|
|
149
|
-
});
|