@restforgejs/platform 4.2.8 → 4.3.2
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 +1 -1
- 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 +3 -2
- package/generators/cli/schema/describe.js +3 -2
- package/generators/cli/schema/diff.js +3 -2
- package/generators/cli/schema/introspect.js +3 -2
- package/generators/cli/schema/list.js +3 -2
- package/generators/cli/schema/migrate.js +3 -2
- package/generators/lib/migration/audit-table-runner.js +213 -215
- package/generators/lib/payload/payload-runner.js +1 -1
- 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/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,173 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const test = require('node:test');
|
|
4
|
-
const assert = require('node:assert');
|
|
5
|
-
|
|
6
|
-
const { defineModel } = require('../../../../../lib/dbschema-kit/define-model');
|
|
7
|
-
const { getDialect } = require('../../../../../lib/dbschema-kit/dialect');
|
|
8
|
-
const { collectIndexes, emitCreateIndexes } = require('../../../../../lib/dbschema-kit/emitters/create-index');
|
|
9
|
-
|
|
10
|
-
const pg = getDialect('postgres');
|
|
11
|
-
const mysql = getDialect('mysql');
|
|
12
|
-
const sqlite = getDialect('sqlite');
|
|
13
|
-
|
|
14
|
-
test('create-index: auto-emit index untuk field yang menjadi localKey FK belongsTo', () => {
|
|
15
|
-
const ir = defineModel('stock_inbound', {
|
|
16
|
-
fields: {
|
|
17
|
-
stock_inbound_id: 'string:36 pk',
|
|
18
|
-
warehouse_id: 'string:36 notnull'
|
|
19
|
-
},
|
|
20
|
-
relations: {
|
|
21
|
-
warehouse: { type: 'belongsTo', localKey: 'warehouse_id', references: 'warehouse_id' }
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
const collected = collectIndexes(ir);
|
|
26
|
-
assert.strictEqual(collected.length, 1);
|
|
27
|
-
assert.deepStrictEqual(collected[0].columns, ['warehouse_id']);
|
|
28
|
-
assert.strictEqual(collected[0].name, 'idx_stock_inbound_warehouse_id');
|
|
29
|
-
|
|
30
|
-
const stmts = emitCreateIndexes(ir, pg);
|
|
31
|
-
assert.deepStrictEqual(stmts, [
|
|
32
|
-
'CREATE INDEX idx_stock_inbound_warehouse_id ON stock_inbound (warehouse_id)'
|
|
33
|
-
]);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test('create-index: user-declared single column index lewat opsi indexes', () => {
|
|
37
|
-
const ir = defineModel('orders', {
|
|
38
|
-
fields: {
|
|
39
|
-
order_id: 'string:36 pk',
|
|
40
|
-
status: 'string:20 notnull'
|
|
41
|
-
},
|
|
42
|
-
indexes: ['status']
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
const stmts = emitCreateIndexes(ir, pg);
|
|
46
|
-
assert.deepStrictEqual(stmts, [
|
|
47
|
-
'CREATE INDEX idx_orders_status ON orders (status)'
|
|
48
|
-
]);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test('create-index: user-declared composite index emit composite CREATE INDEX dengan multiple columns', () => {
|
|
52
|
-
const ir = defineModel('audit', {
|
|
53
|
-
fields: {
|
|
54
|
-
audit_id: 'string:36 pk',
|
|
55
|
-
user_id: 'string:36 notnull',
|
|
56
|
-
action_at: 'timestamp notnull'
|
|
57
|
-
},
|
|
58
|
-
indexes: [['user_id', 'action_at']]
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
const stmts = emitCreateIndexes(ir, pg);
|
|
62
|
-
assert.strictEqual(stmts.length, 1);
|
|
63
|
-
assert.match(stmts[0], /CREATE INDEX idx_audit_user_id_action_at ON audit \(user_id, action_at\)/);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
test('create-index: skip-emit untuk kolom dengan unique shorthand karena UNIQUE constraint sudah implicit indexed', () => {
|
|
67
|
-
const ir = defineModel('users', {
|
|
68
|
-
fields: {
|
|
69
|
-
user_id: 'string:36 pk',
|
|
70
|
-
email: 'string:100 unique notnull'
|
|
71
|
-
},
|
|
72
|
-
indexes: ['email']
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const collected = collectIndexes(ir);
|
|
76
|
-
// Tidak boleh emit idx_users_email karena email sudah punya implicit index dari UNIQUE
|
|
77
|
-
assert.deepStrictEqual(collected, []);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
test('create-index: skip-emit untuk kolom dengan pk shorthand karena PK sudah implicit indexed', () => {
|
|
81
|
-
const ir = defineModel('product', {
|
|
82
|
-
fields: {
|
|
83
|
-
product_id: 'string:36 pk'
|
|
84
|
-
},
|
|
85
|
-
indexes: ['product_id']
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
const collected = collectIndexes(ir);
|
|
89
|
-
assert.deepStrictEqual(collected, []);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
test('create-index: skip-emit composite ketika UNIQUE composite dengan kolom set yang sama sudah ada', () => {
|
|
93
|
-
const ir = defineModel('invoice_line', {
|
|
94
|
-
fields: {
|
|
95
|
-
invoice_id: 'string:36',
|
|
96
|
-
product_id: 'string:36',
|
|
97
|
-
qty: 'integer'
|
|
98
|
-
},
|
|
99
|
-
primaryKey: ['invoice_id', 'product_id'],
|
|
100
|
-
uniques: [['invoice_id', 'product_id']],
|
|
101
|
-
indexes: [['invoice_id', 'product_id']]
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
const collected = collectIndexes(ir);
|
|
105
|
-
// Index composite dengan kolom set sama dengan UNIQUE composite harus skip
|
|
106
|
-
assert.strictEqual(collected.length, 0);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
test('create-index: dedupe ketika auto-FK index dan user-declared index point ke kolom yang sama', () => {
|
|
110
|
-
const ir = defineModel('stock_inbound', {
|
|
111
|
-
fields: {
|
|
112
|
-
stock_inbound_id: 'string:36 pk',
|
|
113
|
-
warehouse_id: 'string:36 notnull'
|
|
114
|
-
},
|
|
115
|
-
indexes: ['warehouse_id'],
|
|
116
|
-
relations: {
|
|
117
|
-
warehouse: { type: 'belongsTo', localKey: 'warehouse_id', references: 'warehouse_id' }
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
const collected = collectIndexes(ir);
|
|
122
|
-
assert.strictEqual(collected.length, 1);
|
|
123
|
-
assert.deepStrictEqual(collected[0].columns, ['warehouse_id']);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
test('create-index: identifier emit tanpa quote di MySQL', () => {
|
|
127
|
-
const ir = defineModel('orders', {
|
|
128
|
-
fields: {
|
|
129
|
-
order_id: 'string:36 pk',
|
|
130
|
-
status: 'string:20 notnull'
|
|
131
|
-
},
|
|
132
|
-
indexes: ['status']
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
const stmts = emitCreateIndexes(ir, mysql);
|
|
136
|
-
assert.deepStrictEqual(stmts, [
|
|
137
|
-
'CREATE INDEX idx_orders_status ON orders (status)'
|
|
138
|
-
]);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
// =====================================================
|
|
142
|
-
// Phase 13: schema namespace support
|
|
143
|
-
// =====================================================
|
|
144
|
-
|
|
145
|
-
test('create-index: PG dengan schema → index name tetap unqualified, ON <schema>.<table> qualified', () => {
|
|
146
|
-
const ir = defineModel('products', {
|
|
147
|
-
schema: 'inventory',
|
|
148
|
-
fields: {
|
|
149
|
-
product_id: 'string:36 pk',
|
|
150
|
-
name: 'string:100 notnull'
|
|
151
|
-
},
|
|
152
|
-
indexes: ['name']
|
|
153
|
-
});
|
|
154
|
-
const stmts = emitCreateIndexes(ir, pg);
|
|
155
|
-
assert.deepStrictEqual(stmts, [
|
|
156
|
-
'CREATE INDEX idx_products_name ON inventory.products (name)'
|
|
157
|
-
]);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
test('create-index: SQLite + schema → throw error via formatTableIdentifier', () => {
|
|
161
|
-
const ir = defineModel('products', {
|
|
162
|
-
schema: 'inventory',
|
|
163
|
-
fields: {
|
|
164
|
-
product_id: 'string:36 pk',
|
|
165
|
-
name: 'string:100 notnull'
|
|
166
|
-
},
|
|
167
|
-
indexes: ['name']
|
|
168
|
-
});
|
|
169
|
-
assert.throws(
|
|
170
|
-
() => emitCreateIndexes(ir, sqlite),
|
|
171
|
-
/^Error: Table 'inventory\.products': SQLite does not support schema-qualified table names/
|
|
172
|
-
);
|
|
173
|
-
});
|
|
@@ -1,376 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const test = require('node:test');
|
|
4
|
-
const assert = require('node:assert');
|
|
5
|
-
|
|
6
|
-
const { defineModel } = require('../../../../../lib/dbschema-kit/define-model');
|
|
7
|
-
const { getDialect } = require('../../../../../lib/dbschema-kit/dialect');
|
|
8
|
-
const { emitCreateTable } = require('../../../../../lib/dbschema-kit/emitters/create-table');
|
|
9
|
-
|
|
10
|
-
const pg = getDialect('postgres');
|
|
11
|
-
const mysql = getDialect('mysql');
|
|
12
|
-
const oracle = getDialect('oracle');
|
|
13
|
-
const sqlite = getDialect('sqlite');
|
|
14
|
-
|
|
15
|
-
test('create-table: tabel sederhana dengan single PK menghasilkan output sesuai snapshot', () => {
|
|
16
|
-
const ir = defineModel('category', {
|
|
17
|
-
fields: {
|
|
18
|
-
category_id: 'string:36 pk',
|
|
19
|
-
category_name: 'string:50 notnull'
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
const sql = emitCreateTable(ir, pg);
|
|
24
|
-
const expected = [
|
|
25
|
-
'CREATE TABLE category (',
|
|
26
|
-
' category_id VARCHAR(36) NOT NULL,',
|
|
27
|
-
' category_name VARCHAR(50) NOT NULL,',
|
|
28
|
-
' CONSTRAINT pk_category PRIMARY KEY (category_id)',
|
|
29
|
-
')'
|
|
30
|
-
].join('\n');
|
|
31
|
-
|
|
32
|
-
assert.strictEqual(sql, expected);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test('create-table: tabel dengan composite PK emit PRIMARY KEY dengan multiple columns', () => {
|
|
36
|
-
const ir = defineModel('order_line', {
|
|
37
|
-
fields: {
|
|
38
|
-
order_id: 'string:36',
|
|
39
|
-
line_number: 'integer',
|
|
40
|
-
qty: 'integer notnull'
|
|
41
|
-
},
|
|
42
|
-
primaryKey: ['order_id', 'line_number']
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
const sql = emitCreateTable(ir, pg);
|
|
46
|
-
assert.match(sql, /CONSTRAINT pk_order_line PRIMARY KEY \(order_id, line_number\)/);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test('create-table: tabel dengan UNIQUE single column emit constraint UNIQUE per kolom', () => {
|
|
50
|
-
const ir = defineModel('users', {
|
|
51
|
-
fields: {
|
|
52
|
-
user_id: 'string:36 pk',
|
|
53
|
-
email: 'string:100 unique notnull'
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
const sql = emitCreateTable(ir, pg);
|
|
58
|
-
assert.match(sql, /CONSTRAINT uq_users_email UNIQUE \(email\)/);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test('create-table: tabel dengan UNIQUE composite emit composite UNIQUE constraint', () => {
|
|
62
|
-
const ir = defineModel('invoice_line', {
|
|
63
|
-
fields: {
|
|
64
|
-
invoice_id: 'string:36',
|
|
65
|
-
product_id: 'string:36',
|
|
66
|
-
qty: 'integer'
|
|
67
|
-
},
|
|
68
|
-
primaryKey: ['invoice_id', 'product_id'],
|
|
69
|
-
uniques: [['invoice_id', 'product_id']]
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
const sql = emitCreateTable(ir, pg);
|
|
73
|
-
assert.match(sql, /CONSTRAINT uq_invoice_line_invoice_id_product_id|CONSTRAINT uq_invoice_line_\S+ UNIQUE \(invoice_id, product_id\)/);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
test('create-table: FK dengan onDelete setNull emit ON DELETE SET NULL', () => {
|
|
77
|
-
const ir = defineModel('stock_inbound', {
|
|
78
|
-
fields: {
|
|
79
|
-
stock_inbound_id: 'string:36 pk',
|
|
80
|
-
supplier_id: 'string:36'
|
|
81
|
-
},
|
|
82
|
-
relations: {
|
|
83
|
-
supplier: { type: 'belongsTo', localKey: 'supplier_id', references: 'supplier_id', onDelete: 'setNull' }
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const sql = emitCreateTable(ir, pg);
|
|
88
|
-
assert.match(sql, /FOREIGN KEY \(supplier_id\) REFERENCES supplier \(supplier_id\) ON DELETE SET NULL/);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
test('create-table: FK tanpa onDelete tidak emit ON DELETE clause', () => {
|
|
92
|
-
const ir = defineModel('stock_inbound', {
|
|
93
|
-
fields: {
|
|
94
|
-
stock_inbound_id: 'string:36 pk',
|
|
95
|
-
warehouse_id: 'string:36 notnull'
|
|
96
|
-
},
|
|
97
|
-
relations: {
|
|
98
|
-
warehouse: { type: 'belongsTo', localKey: 'warehouse_id', references: 'warehouse_id' }
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
const sql = emitCreateTable(ir, pg);
|
|
103
|
-
assert.match(sql, /FOREIGN KEY \(warehouse_id\) REFERENCES warehouse \(warehouse_id\)\s*$/m);
|
|
104
|
-
assert.doesNotMatch(sql, /ON DELETE/);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
test('create-table: CHECK enum operator in emit IN clause dengan list values', () => {
|
|
108
|
-
const ir = defineModel('orders', {
|
|
109
|
-
fields: {
|
|
110
|
-
order_id: 'string:36 pk',
|
|
111
|
-
status: 'string:20 notnull'
|
|
112
|
-
},
|
|
113
|
-
checks: [
|
|
114
|
-
{ field: 'status', in: ['draft', 'confirmed', 'closed'] }
|
|
115
|
-
]
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
const sql = emitCreateTable(ir, pg);
|
|
119
|
-
assert.match(sql, /CONSTRAINT chk_orders_status CHECK \(status IN \('draft', 'confirmed', 'closed'\)\)/);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
test('create-table: CHECK comparison gt dan gte emit operator SQL yang sesuai', () => {
|
|
123
|
-
const ir = defineModel('item', {
|
|
124
|
-
fields: {
|
|
125
|
-
item_id: 'string:36 pk',
|
|
126
|
-
qty: 'integer notnull',
|
|
127
|
-
price: 'decimal:15,2 notnull'
|
|
128
|
-
},
|
|
129
|
-
checks: [
|
|
130
|
-
{ field: 'qty', gt: 0 },
|
|
131
|
-
{ field: 'price', gte: 0 }
|
|
132
|
-
]
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
const sql = emitCreateTable(ir, pg);
|
|
136
|
-
assert.match(sql, /CONSTRAINT chk_item_qty CHECK \(qty > 0\)/);
|
|
137
|
-
assert.match(sql, /CONSTRAINT chk_item_price CHECK \(price >= 0\)/);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
test('create-table: field dengan autoUpdate emit kolom plain TIMESTAMP tanpa DEFAULT', () => {
|
|
141
|
-
const ir = defineModel('audit_log', {
|
|
142
|
-
fields: {
|
|
143
|
-
audit_id: 'string:36 pk',
|
|
144
|
-
updated_at: 'timestamp autoUpdate'
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
const sql = emitCreateTable(ir, pg);
|
|
149
|
-
assert.match(sql, /updated_at TIMESTAMP/);
|
|
150
|
-
assert.doesNotMatch(sql, /updated_at TIMESTAMP[^,\n]*DEFAULT/);
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
test('create-table: field dengan default now() emit DEFAULT CURRENT_TIMESTAMP di Postgres', () => {
|
|
154
|
-
const ir = defineModel('audit_log', {
|
|
155
|
-
fields: {
|
|
156
|
-
audit_id: 'string:36 pk',
|
|
157
|
-
created_at: 'timestamp notnull default:now()'
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
const sql = emitCreateTable(ir, pg);
|
|
162
|
-
assert.match(sql, /created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP/);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
test('create-table: identifier emit tanpa quote di Postgres maupun MySQL', () => {
|
|
166
|
-
const ir = defineModel('user_account', {
|
|
167
|
-
fields: {
|
|
168
|
-
user_id: 'string:36 pk',
|
|
169
|
-
user_name: 'string:50 notnull'
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
const pgSql = emitCreateTable(ir, pg);
|
|
174
|
-
assert.match(pgSql, /CREATE TABLE user_account/);
|
|
175
|
-
assert.match(pgSql, /user_id VARCHAR\(36\)/);
|
|
176
|
-
|
|
177
|
-
const mysqlSql = emitCreateTable(ir, mysql);
|
|
178
|
-
assert.match(mysqlSql, /CREATE TABLE user_account/);
|
|
179
|
-
assert.match(mysqlSql, /user_id VARCHAR\(36\)/);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
test('create-table: boolean default di MySQL menghasilkan literal string bukan boolean native', () => {
|
|
183
|
-
const ir = defineModel('feature_flag', {
|
|
184
|
-
fields: {
|
|
185
|
-
flag_id: 'string:36 pk',
|
|
186
|
-
is_enabled: 'boolean notnull default:true'
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
const pgSql = emitCreateTable(ir, pg);
|
|
191
|
-
assert.match(pgSql, /is_enabled BOOLEAN NOT NULL DEFAULT TRUE/);
|
|
192
|
-
|
|
193
|
-
const mysqlSql = emitCreateTable(ir, mysql);
|
|
194
|
-
assert.match(mysqlSql, /is_enabled VARCHAR\(5\) NOT NULL DEFAULT 'true'/);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
test('create-table: dialect Oracle menggunakan VARCHAR2 untuk string dan NUMBER untuk integer', () => {
|
|
198
|
-
const ir = defineModel('product', {
|
|
199
|
-
fields: {
|
|
200
|
-
product_id: 'string:36 pk',
|
|
201
|
-
stock_qty: 'integer notnull'
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
const sql = emitCreateTable(ir, oracle);
|
|
206
|
-
assert.match(sql, /product_id VARCHAR2\(36\)/);
|
|
207
|
-
assert.match(sql, /stock_qty NUMBER\(10\)/);
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
test('create-table: dialect SQLite emit identifier tanpa quote dan VARCHAR(5) untuk boolean', () => {
|
|
211
|
-
const ir = defineModel('settings', {
|
|
212
|
-
fields: {
|
|
213
|
-
setting_id: 'string:36 pk',
|
|
214
|
-
enabled: 'boolean default:false'
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
const sql = emitCreateTable(ir, sqlite);
|
|
219
|
-
assert.match(sql, /setting_id VARCHAR\(36\)/);
|
|
220
|
-
assert.match(sql, /enabled VARCHAR\(5\) DEFAULT 'false'/);
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
test('create-table: order constraint adalah PK lalu UNIQUE single lalu UNIQUE composite lalu FK lalu CHECK', () => {
|
|
224
|
-
const ir = defineModel('inventory_lot', {
|
|
225
|
-
fields: {
|
|
226
|
-
lot_id: 'string:36 pk',
|
|
227
|
-
lot_code: 'string:50 unique notnull',
|
|
228
|
-
warehouse_id: 'string:36 notnull',
|
|
229
|
-
shelf_code: 'string:20 notnull',
|
|
230
|
-
status: 'string:20 notnull'
|
|
231
|
-
},
|
|
232
|
-
uniques: [['warehouse_id', 'shelf_code']],
|
|
233
|
-
relations: {
|
|
234
|
-
warehouse: { type: 'belongsTo', localKey: 'warehouse_id', references: 'warehouse_id', onDelete: 'restrict' }
|
|
235
|
-
},
|
|
236
|
-
checks: [
|
|
237
|
-
{ field: 'status', in: ['available', 'reserved'] }
|
|
238
|
-
]
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
const sql = emitCreateTable(ir, pg);
|
|
242
|
-
const pkPos = sql.indexOf('PRIMARY KEY');
|
|
243
|
-
const uqSinglePos = sql.indexOf('uq_inventory_lot_lot_code');
|
|
244
|
-
const uqCompositePos = sql.search(/UNIQUE \(warehouse_id, shelf_code\)/);
|
|
245
|
-
const fkPos = sql.indexOf('FOREIGN KEY');
|
|
246
|
-
const chkPos = sql.indexOf('CHECK');
|
|
247
|
-
|
|
248
|
-
assert.ok(pkPos > 0, 'PK harus ada');
|
|
249
|
-
assert.ok(uqSinglePos > pkPos, 'UNIQUE single harus setelah PK');
|
|
250
|
-
assert.ok(uqCompositePos > uqSinglePos, 'UNIQUE composite harus setelah UNIQUE single');
|
|
251
|
-
assert.ok(fkPos > uqCompositePos, 'FK harus setelah UNIQUE composite');
|
|
252
|
-
assert.ok(chkPos > fkPos, 'CHECK harus setelah FK');
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
test('create-table: CHECK pada field yang sama dengan op berbeda menambahkan suffix op', () => {
|
|
256
|
-
const ir = defineModel('item', {
|
|
257
|
-
fields: {
|
|
258
|
-
item_id: 'string:36 pk',
|
|
259
|
-
qty: 'integer notnull'
|
|
260
|
-
},
|
|
261
|
-
checks: [
|
|
262
|
-
{ field: 'qty', gt: 0 },
|
|
263
|
-
{ field: 'qty', lte: 1000 }
|
|
264
|
-
]
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
const sql = emitCreateTable(ir, pg);
|
|
268
|
-
assert.match(sql, /CONSTRAINT chk_item_qty_gt CHECK \(qty > 0\)/);
|
|
269
|
-
assert.match(sql, /CONSTRAINT chk_item_qty_lte CHECK \(qty <= 1000\)/);
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
test('create-table: CHECK string value di-quote dengan single quote dan escape internal apostrophe', () => {
|
|
273
|
-
const ir = defineModel('country', {
|
|
274
|
-
fields: {
|
|
275
|
-
country_id: 'string:36 pk',
|
|
276
|
-
region: 'string:50 notnull'
|
|
277
|
-
},
|
|
278
|
-
checks: [
|
|
279
|
-
{ field: 'region', eq: "O'Hara" }
|
|
280
|
-
]
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
const sql = emitCreateTable(ir, pg);
|
|
284
|
-
assert.match(sql, /CHECK \(region = 'O''Hara'\)/);
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
test('create-table: closing paren di kolom 0 dan tidak ada trailing semicolon', () => {
|
|
288
|
-
const ir = defineModel('foo', {
|
|
289
|
-
fields: {
|
|
290
|
-
id: 'string:36 pk'
|
|
291
|
-
}
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
const sql = emitCreateTable(ir, pg);
|
|
295
|
-
assert.ok(sql.endsWith(')'), 'output diakhiri tanda kurung tutup');
|
|
296
|
-
assert.ok(!sql.endsWith(';'), 'tidak ada trailing semicolon');
|
|
297
|
-
const lines = sql.split('\n');
|
|
298
|
-
assert.strictEqual(lines[lines.length - 1], ')');
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
// =====================================================
|
|
302
|
-
// Phase 13: schema namespace support
|
|
303
|
-
// =====================================================
|
|
304
|
-
|
|
305
|
-
test('create-table: PG dengan schema → CREATE TABLE <schema>.<table>', () => {
|
|
306
|
-
const ir = defineModel('products', {
|
|
307
|
-
schema: 'inventory',
|
|
308
|
-
fields: {
|
|
309
|
-
product_id: 'string:36 pk',
|
|
310
|
-
name: 'string:100 notnull'
|
|
311
|
-
}
|
|
312
|
-
});
|
|
313
|
-
const sql = emitCreateTable(ir, pg);
|
|
314
|
-
assert.match(sql, /^CREATE TABLE inventory\.products \(/);
|
|
315
|
-
assert.match(sql, /CONSTRAINT pk_products PRIMARY KEY \(product_id\)/, 'constraint name TIDAK ikut schema prefix');
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
test('create-table: PG tanpa schema → CREATE TABLE <table> (existing behavior)', () => {
|
|
319
|
-
const ir = defineModel('products', {
|
|
320
|
-
fields: {
|
|
321
|
-
product_id: 'string:36 pk',
|
|
322
|
-
name: 'string:100 notnull'
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
const sql = emitCreateTable(ir, pg);
|
|
326
|
-
assert.match(sql, /^CREATE TABLE products \(/);
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
test('create-table: MySQL dengan schema → CREATE TABLE <schema>.<table>', () => {
|
|
330
|
-
const ir = defineModel('products', {
|
|
331
|
-
schema: 'inventory',
|
|
332
|
-
fields: { product_id: 'string:36 pk', name: 'string:100 notnull' }
|
|
333
|
-
});
|
|
334
|
-
const sql = emitCreateTable(ir, mysql);
|
|
335
|
-
assert.match(sql, /^CREATE TABLE inventory\.products \(/);
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
test('create-table: Oracle dengan schema → CREATE TABLE <schema>.<table> (default emit prefix)', () => {
|
|
339
|
-
const ir = defineModel('products', {
|
|
340
|
-
schema: 'inventory',
|
|
341
|
-
fields: { product_id: 'string:36 pk', name: 'string:100 notnull' }
|
|
342
|
-
});
|
|
343
|
-
const sql = emitCreateTable(ir, oracle);
|
|
344
|
-
assert.match(sql, /^CREATE TABLE inventory\.products \(/);
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
test('create-table: SQLite + schema → throw error eksplisit', () => {
|
|
348
|
-
const ir = defineModel('products', {
|
|
349
|
-
schema: 'inventory',
|
|
350
|
-
fields: { product_id: 'string:36 pk', name: 'string:100 notnull' }
|
|
351
|
-
});
|
|
352
|
-
assert.throws(
|
|
353
|
-
() => emitCreateTable(ir, sqlite),
|
|
354
|
-
/^Error: Table 'inventory\.products': SQLite does not support schema-qualified table names/
|
|
355
|
-
);
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
test('create-table: FK target qualified emit REFERENCES <schema>.<table>', () => {
|
|
359
|
-
const ir = defineModel('products', {
|
|
360
|
-
schema: 'inventory',
|
|
361
|
-
fields: {
|
|
362
|
-
product_id: 'string:36 pk',
|
|
363
|
-
category_id: 'string:36'
|
|
364
|
-
},
|
|
365
|
-
relations: {
|
|
366
|
-
category: {
|
|
367
|
-
type: 'belongsTo',
|
|
368
|
-
target: 'inventory.categories',
|
|
369
|
-
localKey: 'category_id',
|
|
370
|
-
references: 'category_id'
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
});
|
|
374
|
-
const sql = emitCreateTable(ir, pg);
|
|
375
|
-
assert.match(sql, /REFERENCES inventory\.categories \(category_id\)/);
|
|
376
|
-
});
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const test = require('node:test');
|
|
4
|
-
const assert = require('node:assert');
|
|
5
|
-
|
|
6
|
-
const { defineModel } = require('../../../../../lib/dbschema-kit/define-model');
|
|
7
|
-
const { getDialect } = require('../../../../../lib/dbschema-kit/dialect');
|
|
8
|
-
const { emitDropTable } = require('../../../../../lib/dbschema-kit/emitters/drop-table');
|
|
9
|
-
|
|
10
|
-
function makeIr(tableName, schemaName) {
|
|
11
|
-
const opts = { fields: { id: 'string:36 pk' } };
|
|
12
|
-
if (schemaName) opts.schema = schemaName;
|
|
13
|
-
return defineModel(tableName, opts);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
test('drop-table: PostgreSQL menghasilkan DROP TABLE IF EXISTS dengan CASCADE', () => {
|
|
17
|
-
const sql = emitDropTable(makeIr('stock_inbound'), getDialect('postgres'));
|
|
18
|
-
assert.strictEqual(sql, 'DROP TABLE IF EXISTS stock_inbound CASCADE');
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
test('drop-table: MySQL menghasilkan DROP TABLE IF EXISTS tanpa quote', () => {
|
|
22
|
-
const sql = emitDropTable(makeIr('stock_inbound'), getDialect('mysql'));
|
|
23
|
-
assert.strictEqual(sql, 'DROP TABLE IF EXISTS stock_inbound');
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
test('drop-table: SQLite menghasilkan DROP TABLE IF EXISTS tanpa CASCADE', () => {
|
|
27
|
-
const sql = emitDropTable(makeIr('stock_inbound'), getDialect('sqlite'));
|
|
28
|
-
assert.strictEqual(sql, 'DROP TABLE IF EXISTS stock_inbound');
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test('drop-table: Oracle menghasilkan PL/SQL block dengan EXCEPTION handling untuk ORA-00942', () => {
|
|
32
|
-
const sql = emitDropTable(makeIr('stock_inbound'), getDialect('oracle'));
|
|
33
|
-
assert.match(sql, /BEGIN/);
|
|
34
|
-
assert.match(sql, /EXECUTE IMMEDIATE 'DROP TABLE stock_inbound CASCADE CONSTRAINTS'/);
|
|
35
|
-
assert.match(sql, /EXCEPTION/);
|
|
36
|
-
assert.match(sql, /WHEN OTHERS THEN/);
|
|
37
|
-
assert.match(sql, /SQLCODE != -942/);
|
|
38
|
-
assert.match(sql, /RAISE/);
|
|
39
|
-
assert.match(sql, /END;/);
|
|
40
|
-
assert.ok(sql.endsWith('/'), 'Oracle output diakhiri dengan terminator /');
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test('drop-table: dialect tidak dikenal melempar error eksplisit', () => {
|
|
44
|
-
const fakeDialect = {
|
|
45
|
-
name: 'mssql',
|
|
46
|
-
formatTableIdentifier: (ir) => ir.tableName
|
|
47
|
-
};
|
|
48
|
-
assert.throws(
|
|
49
|
-
() => emitDropTable(makeIr('foo'), fakeDialect),
|
|
50
|
-
/Unsupported dialect: mssql/
|
|
51
|
-
);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// =====================================================
|
|
55
|
-
// Phase 13: schema namespace support
|
|
56
|
-
// =====================================================
|
|
57
|
-
|
|
58
|
-
test('drop-table: PG dengan schema emit DROP TABLE IF EXISTS <schema>.<table> CASCADE', () => {
|
|
59
|
-
const sql = emitDropTable(makeIr('products', 'inventory'), getDialect('postgres'));
|
|
60
|
-
assert.strictEqual(sql, 'DROP TABLE IF EXISTS inventory.products CASCADE');
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
test('drop-table: MySQL dengan schema emit DROP TABLE IF EXISTS <schema>.<table>', () => {
|
|
64
|
-
const sql = emitDropTable(makeIr('products', 'inventory'), getDialect('mysql'));
|
|
65
|
-
assert.strictEqual(sql, 'DROP TABLE IF EXISTS inventory.products');
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
test('drop-table: Oracle dengan schema emit DROP TABLE <schema>.<table> CASCADE CONSTRAINTS', () => {
|
|
69
|
-
const sql = emitDropTable(makeIr('products', 'inventory'), getDialect('oracle'));
|
|
70
|
-
assert.match(sql, /EXECUTE IMMEDIATE 'DROP TABLE inventory\.products CASCADE CONSTRAINTS'/);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
test('drop-table: SQLite + schema throw error eksplisit', () => {
|
|
74
|
-
assert.throws(
|
|
75
|
-
() => emitDropTable(makeIr('products', 'inventory'), getDialect('sqlite')),
|
|
76
|
-
/^Error: Table 'inventory\.products': SQLite does not support schema-qualified table names/
|
|
77
|
-
);
|
|
78
|
-
});
|
package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/category.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
module.exports = ({ defineModel }) => defineModel('category', {
|
|
4
|
-
fields: {
|
|
5
|
-
category_id: 'uuid pk',
|
|
6
|
-
category_code: 'string:20 unique notnull',
|
|
7
|
-
category_name: 'string:100 notnull',
|
|
8
|
-
is_active: 'boolean default:true'
|
|
9
|
-
},
|
|
10
|
-
indexes: ['is_active']
|
|
11
|
-
});
|
package/generators/tests/unit/lib/dbschema-kit/fixtures/integration/mini-inventory/item_product.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
module.exports = ({ defineModel }) => defineModel('item_product', {
|
|
4
|
-
fields: {
|
|
5
|
-
item_product_id: 'uuid pk',
|
|
6
|
-
product_code: 'string:20 unique notnull',
|
|
7
|
-
product_name: 'string:100 notnull',
|
|
8
|
-
category_id: 'uuid fk:category.category_id notnull',
|
|
9
|
-
is_active: 'boolean default:true'
|
|
10
|
-
}
|
|
11
|
-
});
|