@contember/cli 2.1.0-beta.2 → 2.2.0-alpha.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/CLAUDE.md +14 -1
- package/dist/development/index.cjs +5 -0
- package/dist/development/index.cjs.map +1 -0
- package/dist/development/index.js +5 -0
- package/dist/development/index.js.map +1 -0
- package/dist/development/run.cjs +3 -3
- package/dist/development/run.cjs.map +1 -1
- package/dist/development/run.js.map +1 -1
- package/dist/development/src/commands/actions/ActionsGetEventCommand.cjs.map +1 -1
- package/dist/development/src/commands/actions/ActionsGetEventCommand.js.map +1 -1
- package/dist/development/src/commands/actions/ActionsListFailedEventsCommand.cjs.map +1 -1
- package/dist/development/src/commands/actions/ActionsListFailedEventsCommand.js.map +1 -1
- package/dist/development/src/commands/actions/ActionsListVariablesCommand.cjs.map +1 -1
- package/dist/development/src/commands/actions/ActionsListVariablesCommand.js.map +1 -1
- package/dist/development/src/commands/actions/ActionsRetryEventCommand.cjs.map +1 -1
- package/dist/development/src/commands/actions/ActionsRetryEventCommand.js.map +1 -1
- package/dist/development/src/commands/actions/ActionsSetVariablesCommand.cjs.map +1 -1
- package/dist/development/src/commands/actions/ActionsSetVariablesCommand.js.map +1 -1
- package/dist/development/src/commands/actions/ActionsStopEventCommand.cjs.map +1 -1
- package/dist/development/src/commands/actions/ActionsStopEventCommand.js.map +1 -1
- package/dist/development/src/commands/deploy/DeployCommand.cjs +3 -1
- package/dist/development/src/commands/deploy/DeployCommand.cjs.map +1 -1
- package/dist/development/src/commands/deploy/DeployCommand.js +3 -1
- package/dist/development/src/commands/deploy/DeployCommand.js.map +1 -1
- package/dist/development/src/commands/migrations/MigrationAmendCommand.cjs +26 -4
- package/dist/development/src/commands/migrations/MigrationAmendCommand.cjs.map +1 -1
- package/dist/development/src/commands/migrations/MigrationAmendCommand.js +26 -4
- package/dist/development/src/commands/migrations/MigrationAmendCommand.js.map +1 -1
- package/dist/development/src/commands/migrations/MigrationDescribeCommand.cjs.map +1 -1
- package/dist/development/src/commands/migrations/MigrationDescribeCommand.js.map +1 -1
- package/dist/development/src/commands/migrations/MigrationDiffCommand.cjs +39 -3
- package/dist/development/src/commands/migrations/MigrationDiffCommand.cjs.map +1 -1
- package/dist/development/src/commands/migrations/MigrationDiffCommand.js +39 -3
- package/dist/development/src/commands/migrations/MigrationDiffCommand.js.map +1 -1
- package/dist/development/src/commands/migrations/MigrationExecuteCommand.cjs +3 -1
- package/dist/development/src/commands/migrations/MigrationExecuteCommand.cjs.map +1 -1
- package/dist/development/src/commands/migrations/MigrationExecuteCommand.js +3 -1
- package/dist/development/src/commands/migrations/MigrationExecuteCommand.js.map +1 -1
- package/dist/development/src/commands/migrations/MigrationInitStateCommand.cjs +26 -0
- package/dist/development/src/commands/migrations/MigrationInitStateCommand.cjs.map +1 -0
- package/dist/development/src/commands/migrations/MigrationInitStateCommand.js +26 -0
- package/dist/development/src/commands/migrations/MigrationInitStateCommand.js.map +1 -0
- package/dist/development/src/commands/migrations/MigrationRebaseCommand.cjs.map +1 -1
- package/dist/development/src/commands/migrations/MigrationRebaseCommand.js.map +1 -1
- package/dist/development/src/commands/migrations/MigrationSnapshotCommand.cjs +28 -0
- package/dist/development/src/commands/migrations/MigrationSnapshotCommand.cjs.map +1 -0
- package/dist/development/src/commands/migrations/MigrationSnapshotCommand.js +28 -0
- package/dist/development/src/commands/migrations/MigrationSnapshotCommand.js.map +1 -0
- package/dist/development/src/commands/migrations/MigrationStatusCommand.cjs.map +1 -1
- package/dist/development/src/commands/migrations/MigrationStatusCommand.js.map +1 -1
- package/dist/development/src/commands/migrations/MigrationVerifySnapshotCommand.cjs +23 -0
- package/dist/development/src/commands/migrations/MigrationVerifySnapshotCommand.cjs.map +1 -0
- package/dist/development/src/commands/migrations/MigrationVerifySnapshotCommand.js +23 -0
- package/dist/development/src/commands/migrations/MigrationVerifySnapshotCommand.js.map +1 -0
- package/dist/development/src/commands/project/ProjectGenerateDocumentationCommand.cjs +2 -2
- package/dist/development/src/commands/project/ProjectGenerateDocumentationCommand.cjs.map +1 -1
- package/dist/development/src/commands/project/ProjectGenerateDocumentationCommand.js.map +1 -1
- package/dist/development/src/commands/project/ProjectPrintSchemaCommand.cjs.map +1 -1
- package/dist/development/src/commands/project/ProjectPrintSchemaCommand.js.map +1 -1
- package/dist/development/src/commands/project/ProjectValidateCommand.cjs.map +1 -1
- package/dist/development/src/commands/project/ProjectValidateCommand.js.map +1 -1
- package/dist/development/src/commands/tenant/TenantApplyCommand.cjs +39 -0
- package/dist/development/src/commands/tenant/TenantApplyCommand.cjs.map +1 -0
- package/dist/development/src/commands/tenant/TenantApplyCommand.js +39 -0
- package/dist/development/src/commands/tenant/TenantApplyCommand.js.map +1 -0
- package/dist/development/src/commands/transfer/ExportCommand.cjs.map +1 -1
- package/dist/development/src/commands/transfer/ExportCommand.js.map +1 -1
- package/dist/development/src/commands/transfer/ImportCommand.cjs.map +1 -1
- package/dist/development/src/commands/transfer/ImportCommand.js.map +1 -1
- package/dist/development/src/commands/transfer/TransferCommand.cjs.map +1 -1
- package/dist/development/src/commands/transfer/TransferCommand.js.map +1 -1
- package/dist/development/src/commands/workspace/WorkspaceUpdateApiCommand.cjs.map +1 -1
- package/dist/development/src/commands/workspace/WorkspaceUpdateApiCommand.js.map +1 -1
- package/dist/development/src/consts.cjs +2 -2
- package/dist/development/src/consts.cjs.map +1 -1
- package/dist/development/src/dic.cjs +60 -10
- package/dist/development/src/dic.cjs.map +1 -1
- package/dist/development/src/dic.js +61 -11
- package/dist/development/src/dic.js.map +1 -1
- package/dist/development/src/lib/SystemClientProvider.cjs.map +1 -1
- package/dist/development/src/lib/SystemClientProvider.js.map +1 -1
- package/dist/development/src/lib/TenantClientProvider.cjs.map +1 -1
- package/dist/development/src/lib/TenantClientProvider.js.map +1 -1
- package/dist/development/src/lib/VersionChecker.cjs +2 -2
- package/dist/development/src/lib/VersionChecker.cjs.map +1 -1
- package/dist/development/src/lib/VersionChecker.js.map +1 -1
- package/dist/development/src/lib/admin/AdminClient.cjs.map +1 -1
- package/dist/development/src/lib/admin/AdminClient.js.map +1 -1
- package/dist/development/src/lib/admin/AdminDeployer.cjs.map +1 -1
- package/dist/development/src/lib/admin/AdminDeployer.js.map +1 -1
- package/dist/development/src/lib/fs/DockerComposeManager.cjs +10 -10
- package/dist/development/src/lib/fs/DockerComposeManager.cjs.map +1 -1
- package/dist/development/src/lib/fs/DockerComposeManager.js.map +1 -1
- package/dist/development/src/lib/fs/YamlHandler.cjs.map +1 -1
- package/dist/development/src/lib/fs/YamlHandler.js.map +1 -1
- package/dist/development/src/lib/js/EsBuildBuilder.cjs.map +1 -1
- package/dist/development/src/lib/js/EsBuildBuilder.js.map +1 -1
- package/dist/development/src/lib/js/EvalExecutor.cjs.map +1 -1
- package/dist/development/src/lib/js/EvalExecutor.js.map +1 -1
- package/dist/development/src/lib/js/JsCodeRunner.cjs.map +1 -1
- package/dist/development/src/lib/js/JsCodeRunner.js.map +1 -1
- package/dist/development/src/lib/migrations/MigrationExecutionFacade.cjs +78 -18
- package/dist/development/src/lib/migrations/MigrationExecutionFacade.cjs.map +1 -1
- package/dist/development/src/lib/migrations/MigrationExecutionFacade.js +79 -19
- package/dist/development/src/lib/migrations/MigrationExecutionFacade.js.map +1 -1
- package/dist/development/src/lib/migrations/MigrationPrinter.cjs.map +1 -1
- package/dist/development/src/lib/migrations/MigrationPrinter.js.map +1 -1
- package/dist/development/src/lib/migrations/MigrationRebaseFacade.cjs +5 -1
- package/dist/development/src/lib/migrations/MigrationRebaseFacade.cjs.map +1 -1
- package/dist/development/src/lib/migrations/MigrationRebaseFacade.js +5 -1
- package/dist/development/src/lib/migrations/MigrationRebaseFacade.js.map +1 -1
- package/dist/development/src/lib/migrations/MigrationSnapshotFacade.cjs +171 -0
- package/dist/development/src/lib/migrations/MigrationSnapshotFacade.cjs.map +1 -0
- package/dist/development/src/lib/migrations/MigrationSnapshotFacade.js +171 -0
- package/dist/development/src/lib/migrations/MigrationSnapshotFacade.js.map +1 -0
- package/dist/development/src/lib/migrations/MigrationsStatusFacade.cjs.map +1 -1
- package/dist/development/src/lib/migrations/MigrationsStatusFacade.js.map +1 -1
- package/dist/development/src/lib/migrations/MigrationsValidator.cjs.map +1 -1
- package/dist/development/src/lib/migrations/MigrationsValidator.js.map +1 -1
- package/dist/development/src/lib/project/RemoteProjectProvider.cjs.map +1 -1
- package/dist/development/src/lib/project/RemoteProjectProvider.js.map +1 -1
- package/dist/development/src/lib/project/RemoteProjectResolver.cjs.map +1 -1
- package/dist/development/src/lib/project/RemoteProjectResolver.js.map +1 -1
- package/dist/development/src/lib/project/docs/components/EntityInfo.cjs.map +1 -1
- package/dist/development/src/lib/project/docs/components/EntityInfo.js.map +1 -1
- package/dist/development/src/lib/project/docs/components/EntityLink.cjs.map +1 -1
- package/dist/development/src/lib/project/docs/components/EntityLink.js.map +1 -1
- package/dist/development/src/lib/project/docs/components/FieldLink.cjs.map +1 -1
- package/dist/development/src/lib/project/docs/components/FieldLink.js.map +1 -1
- package/dist/development/src/lib/project/docs/components/FieldPermissions.cjs.map +1 -1
- package/dist/development/src/lib/project/docs/components/FieldPermissions.js.map +1 -1
- package/dist/development/src/lib/project/docs/components/FieldType.cjs.map +1 -1
- package/dist/development/src/lib/project/docs/components/FieldType.js.map +1 -1
- package/dist/development/src/lib/project/docs/components/OnDelete.cjs.map +1 -1
- package/dist/development/src/lib/project/docs/components/OnDelete.js.map +1 -1
- package/dist/development/src/lib/project/docs/components/ProjectInfo.cjs.map +1 -1
- package/dist/development/src/lib/project/docs/components/ProjectInfo.js.map +1 -1
- package/dist/development/src/lib/project/docs/projectDescribe.cjs.map +1 -1
- package/dist/development/src/lib/project/docs/projectDescribe.js.map +1 -1
- package/dist/development/src/lib/schema/SchemaLoader.cjs +5 -5
- package/dist/development/src/lib/schema/SchemaLoader.cjs.map +1 -1
- package/dist/development/src/lib/schema/SchemaLoader.js.map +1 -1
- package/dist/development/src/lib/schema/SchemaValidationHelper.cjs.map +1 -1
- package/dist/development/src/lib/schema/SchemaValidationHelper.js.map +1 -1
- package/dist/development/src/lib/tenant/TenantClient.cjs +75 -12
- package/dist/development/src/lib/tenant/TenantClient.cjs.map +1 -1
- package/dist/development/src/lib/tenant/TenantClient.js +75 -12
- package/dist/development/src/lib/tenant/TenantClient.js.map +1 -1
- package/dist/development/src/lib/tenant/TenantConfigApplier.cjs +55 -0
- package/dist/development/src/lib/tenant/TenantConfigApplier.cjs.map +1 -0
- package/dist/development/src/lib/tenant/TenantConfigApplier.js +55 -0
- package/dist/development/src/lib/tenant/TenantConfigApplier.js.map +1 -0
- package/dist/development/src/lib/tenant/TenantConfigLoader.cjs +32 -0
- package/dist/development/src/lib/tenant/TenantConfigLoader.cjs.map +1 -0
- package/dist/development/src/lib/tenant/TenantConfigLoader.js +32 -0
- package/dist/development/src/lib/tenant/TenantConfigLoader.js.map +1 -0
- package/dist/development/src/lib/tenant/tenantConfig.cjs +5 -0
- package/dist/development/src/lib/tenant/tenantConfig.cjs.map +1 -0
- package/dist/development/src/lib/tenant/tenantConfig.js +5 -0
- package/dist/development/src/lib/tenant/tenantConfig.js.map +1 -0
- package/dist/development/src/lib/transfer/DataTransferClient.cjs.map +1 -1
- package/dist/development/src/lib/transfer/DataTransferClient.js.map +1 -1
- package/dist/development/src/lib/workspace/WorkspaceResolver.cjs +6 -6
- package/dist/development/src/lib/workspace/WorkspaceResolver.cjs.map +1 -1
- package/dist/development/src/lib/workspace/WorkspaceResolver.js.map +1 -1
- package/dist/production/index.cjs +5 -0
- package/dist/production/index.cjs.map +1 -0
- package/dist/production/index.js +5 -0
- package/dist/production/index.js.map +1 -0
- package/dist/production/run.cjs +3 -3
- package/dist/production/run.cjs.map +1 -1
- package/dist/production/run.js.map +1 -1
- package/dist/production/src/commands/actions/ActionsGetEventCommand.cjs.map +1 -1
- package/dist/production/src/commands/actions/ActionsGetEventCommand.js.map +1 -1
- package/dist/production/src/commands/actions/ActionsListFailedEventsCommand.cjs.map +1 -1
- package/dist/production/src/commands/actions/ActionsListFailedEventsCommand.js.map +1 -1
- package/dist/production/src/commands/actions/ActionsListVariablesCommand.cjs.map +1 -1
- package/dist/production/src/commands/actions/ActionsListVariablesCommand.js.map +1 -1
- package/dist/production/src/commands/actions/ActionsRetryEventCommand.cjs.map +1 -1
- package/dist/production/src/commands/actions/ActionsRetryEventCommand.js.map +1 -1
- package/dist/production/src/commands/actions/ActionsSetVariablesCommand.cjs.map +1 -1
- package/dist/production/src/commands/actions/ActionsSetVariablesCommand.js.map +1 -1
- package/dist/production/src/commands/actions/ActionsStopEventCommand.cjs.map +1 -1
- package/dist/production/src/commands/actions/ActionsStopEventCommand.js.map +1 -1
- package/dist/production/src/commands/deploy/DeployCommand.cjs +3 -1
- package/dist/production/src/commands/deploy/DeployCommand.cjs.map +1 -1
- package/dist/production/src/commands/deploy/DeployCommand.js +3 -1
- package/dist/production/src/commands/deploy/DeployCommand.js.map +1 -1
- package/dist/production/src/commands/migrations/MigrationAmendCommand.cjs +26 -4
- package/dist/production/src/commands/migrations/MigrationAmendCommand.cjs.map +1 -1
- package/dist/production/src/commands/migrations/MigrationAmendCommand.js +26 -4
- package/dist/production/src/commands/migrations/MigrationAmendCommand.js.map +1 -1
- package/dist/production/src/commands/migrations/MigrationDescribeCommand.cjs.map +1 -1
- package/dist/production/src/commands/migrations/MigrationDescribeCommand.js.map +1 -1
- package/dist/production/src/commands/migrations/MigrationDiffCommand.cjs +39 -3
- package/dist/production/src/commands/migrations/MigrationDiffCommand.cjs.map +1 -1
- package/dist/production/src/commands/migrations/MigrationDiffCommand.js +39 -3
- package/dist/production/src/commands/migrations/MigrationDiffCommand.js.map +1 -1
- package/dist/production/src/commands/migrations/MigrationExecuteCommand.cjs +3 -1
- package/dist/production/src/commands/migrations/MigrationExecuteCommand.cjs.map +1 -1
- package/dist/production/src/commands/migrations/MigrationExecuteCommand.js +3 -1
- package/dist/production/src/commands/migrations/MigrationExecuteCommand.js.map +1 -1
- package/dist/production/src/commands/migrations/MigrationInitStateCommand.cjs +26 -0
- package/dist/production/src/commands/migrations/MigrationInitStateCommand.cjs.map +1 -0
- package/dist/production/src/commands/migrations/MigrationInitStateCommand.js +26 -0
- package/dist/production/src/commands/migrations/MigrationInitStateCommand.js.map +1 -0
- package/dist/production/src/commands/migrations/MigrationRebaseCommand.cjs.map +1 -1
- package/dist/production/src/commands/migrations/MigrationRebaseCommand.js.map +1 -1
- package/dist/production/src/commands/migrations/MigrationSnapshotCommand.cjs +28 -0
- package/dist/production/src/commands/migrations/MigrationSnapshotCommand.cjs.map +1 -0
- package/dist/production/src/commands/migrations/MigrationSnapshotCommand.js +28 -0
- package/dist/production/src/commands/migrations/MigrationSnapshotCommand.js.map +1 -0
- package/dist/production/src/commands/migrations/MigrationStatusCommand.cjs.map +1 -1
- package/dist/production/src/commands/migrations/MigrationStatusCommand.js.map +1 -1
- package/dist/production/src/commands/migrations/MigrationVerifySnapshotCommand.cjs +23 -0
- package/dist/production/src/commands/migrations/MigrationVerifySnapshotCommand.cjs.map +1 -0
- package/dist/production/src/commands/migrations/MigrationVerifySnapshotCommand.js +23 -0
- package/dist/production/src/commands/migrations/MigrationVerifySnapshotCommand.js.map +1 -0
- package/dist/production/src/commands/project/ProjectGenerateDocumentationCommand.cjs +2 -2
- package/dist/production/src/commands/project/ProjectGenerateDocumentationCommand.cjs.map +1 -1
- package/dist/production/src/commands/project/ProjectGenerateDocumentationCommand.js.map +1 -1
- package/dist/production/src/commands/project/ProjectPrintSchemaCommand.cjs.map +1 -1
- package/dist/production/src/commands/project/ProjectPrintSchemaCommand.js.map +1 -1
- package/dist/production/src/commands/project/ProjectValidateCommand.cjs.map +1 -1
- package/dist/production/src/commands/project/ProjectValidateCommand.js.map +1 -1
- package/dist/production/src/commands/tenant/TenantApplyCommand.cjs +39 -0
- package/dist/production/src/commands/tenant/TenantApplyCommand.cjs.map +1 -0
- package/dist/production/src/commands/tenant/TenantApplyCommand.js +39 -0
- package/dist/production/src/commands/tenant/TenantApplyCommand.js.map +1 -0
- package/dist/production/src/commands/transfer/ExportCommand.cjs.map +1 -1
- package/dist/production/src/commands/transfer/ExportCommand.js.map +1 -1
- package/dist/production/src/commands/transfer/ImportCommand.cjs.map +1 -1
- package/dist/production/src/commands/transfer/ImportCommand.js.map +1 -1
- package/dist/production/src/commands/transfer/TransferCommand.cjs.map +1 -1
- package/dist/production/src/commands/transfer/TransferCommand.js.map +1 -1
- package/dist/production/src/commands/workspace/WorkspaceUpdateApiCommand.cjs.map +1 -1
- package/dist/production/src/commands/workspace/WorkspaceUpdateApiCommand.js.map +1 -1
- package/dist/production/src/consts.cjs +2 -2
- package/dist/production/src/consts.cjs.map +1 -1
- package/dist/production/src/dic.cjs +60 -10
- package/dist/production/src/dic.cjs.map +1 -1
- package/dist/production/src/dic.js +61 -11
- package/dist/production/src/dic.js.map +1 -1
- package/dist/production/src/lib/SystemClientProvider.cjs.map +1 -1
- package/dist/production/src/lib/SystemClientProvider.js.map +1 -1
- package/dist/production/src/lib/TenantClientProvider.cjs.map +1 -1
- package/dist/production/src/lib/TenantClientProvider.js.map +1 -1
- package/dist/production/src/lib/VersionChecker.cjs +2 -2
- package/dist/production/src/lib/VersionChecker.cjs.map +1 -1
- package/dist/production/src/lib/VersionChecker.js.map +1 -1
- package/dist/production/src/lib/admin/AdminClient.cjs.map +1 -1
- package/dist/production/src/lib/admin/AdminClient.js.map +1 -1
- package/dist/production/src/lib/admin/AdminDeployer.cjs.map +1 -1
- package/dist/production/src/lib/admin/AdminDeployer.js.map +1 -1
- package/dist/production/src/lib/fs/DockerComposeManager.cjs +10 -10
- package/dist/production/src/lib/fs/DockerComposeManager.cjs.map +1 -1
- package/dist/production/src/lib/fs/DockerComposeManager.js.map +1 -1
- package/dist/production/src/lib/fs/YamlHandler.cjs.map +1 -1
- package/dist/production/src/lib/fs/YamlHandler.js.map +1 -1
- package/dist/production/src/lib/js/EsBuildBuilder.cjs.map +1 -1
- package/dist/production/src/lib/js/EsBuildBuilder.js.map +1 -1
- package/dist/production/src/lib/js/EvalExecutor.cjs.map +1 -1
- package/dist/production/src/lib/js/EvalExecutor.js.map +1 -1
- package/dist/production/src/lib/js/JsCodeRunner.cjs.map +1 -1
- package/dist/production/src/lib/js/JsCodeRunner.js.map +1 -1
- package/dist/production/src/lib/migrations/MigrationExecutionFacade.cjs +78 -18
- package/dist/production/src/lib/migrations/MigrationExecutionFacade.cjs.map +1 -1
- package/dist/production/src/lib/migrations/MigrationExecutionFacade.js +79 -19
- package/dist/production/src/lib/migrations/MigrationExecutionFacade.js.map +1 -1
- package/dist/production/src/lib/migrations/MigrationPrinter.cjs.map +1 -1
- package/dist/production/src/lib/migrations/MigrationPrinter.js.map +1 -1
- package/dist/production/src/lib/migrations/MigrationRebaseFacade.cjs +5 -1
- package/dist/production/src/lib/migrations/MigrationRebaseFacade.cjs.map +1 -1
- package/dist/production/src/lib/migrations/MigrationRebaseFacade.js +5 -1
- package/dist/production/src/lib/migrations/MigrationRebaseFacade.js.map +1 -1
- package/dist/production/src/lib/migrations/MigrationSnapshotFacade.cjs +171 -0
- package/dist/production/src/lib/migrations/MigrationSnapshotFacade.cjs.map +1 -0
- package/dist/production/src/lib/migrations/MigrationSnapshotFacade.js +171 -0
- package/dist/production/src/lib/migrations/MigrationSnapshotFacade.js.map +1 -0
- package/dist/production/src/lib/migrations/MigrationsStatusFacade.cjs.map +1 -1
- package/dist/production/src/lib/migrations/MigrationsStatusFacade.js.map +1 -1
- package/dist/production/src/lib/migrations/MigrationsValidator.cjs.map +1 -1
- package/dist/production/src/lib/migrations/MigrationsValidator.js.map +1 -1
- package/dist/production/src/lib/project/RemoteProjectProvider.cjs.map +1 -1
- package/dist/production/src/lib/project/RemoteProjectProvider.js.map +1 -1
- package/dist/production/src/lib/project/RemoteProjectResolver.cjs.map +1 -1
- package/dist/production/src/lib/project/RemoteProjectResolver.js.map +1 -1
- package/dist/production/src/lib/project/docs/components/EntityInfo.cjs.map +1 -1
- package/dist/production/src/lib/project/docs/components/EntityInfo.js.map +1 -1
- package/dist/production/src/lib/project/docs/components/EntityLink.cjs.map +1 -1
- package/dist/production/src/lib/project/docs/components/EntityLink.js.map +1 -1
- package/dist/production/src/lib/project/docs/components/FieldLink.cjs.map +1 -1
- package/dist/production/src/lib/project/docs/components/FieldLink.js.map +1 -1
- package/dist/production/src/lib/project/docs/components/FieldPermissions.cjs.map +1 -1
- package/dist/production/src/lib/project/docs/components/FieldPermissions.js.map +1 -1
- package/dist/production/src/lib/project/docs/components/FieldType.cjs.map +1 -1
- package/dist/production/src/lib/project/docs/components/FieldType.js.map +1 -1
- package/dist/production/src/lib/project/docs/components/OnDelete.cjs.map +1 -1
- package/dist/production/src/lib/project/docs/components/OnDelete.js.map +1 -1
- package/dist/production/src/lib/project/docs/components/ProjectInfo.cjs.map +1 -1
- package/dist/production/src/lib/project/docs/components/ProjectInfo.js.map +1 -1
- package/dist/production/src/lib/project/docs/projectDescribe.cjs.map +1 -1
- package/dist/production/src/lib/project/docs/projectDescribe.js.map +1 -1
- package/dist/production/src/lib/schema/SchemaLoader.cjs +5 -5
- package/dist/production/src/lib/schema/SchemaLoader.cjs.map +1 -1
- package/dist/production/src/lib/schema/SchemaLoader.js.map +1 -1
- package/dist/production/src/lib/schema/SchemaValidationHelper.cjs.map +1 -1
- package/dist/production/src/lib/schema/SchemaValidationHelper.js.map +1 -1
- package/dist/production/src/lib/tenant/TenantClient.cjs +75 -12
- package/dist/production/src/lib/tenant/TenantClient.cjs.map +1 -1
- package/dist/production/src/lib/tenant/TenantClient.js +75 -12
- package/dist/production/src/lib/tenant/TenantClient.js.map +1 -1
- package/dist/production/src/lib/tenant/TenantConfigApplier.cjs +55 -0
- package/dist/production/src/lib/tenant/TenantConfigApplier.cjs.map +1 -0
- package/dist/production/src/lib/tenant/TenantConfigApplier.js +55 -0
- package/dist/production/src/lib/tenant/TenantConfigApplier.js.map +1 -0
- package/dist/production/src/lib/tenant/TenantConfigLoader.cjs +32 -0
- package/dist/production/src/lib/tenant/TenantConfigLoader.cjs.map +1 -0
- package/dist/production/src/lib/tenant/TenantConfigLoader.js +32 -0
- package/dist/production/src/lib/tenant/TenantConfigLoader.js.map +1 -0
- package/dist/production/src/lib/tenant/tenantConfig.cjs +5 -0
- package/dist/production/src/lib/tenant/tenantConfig.cjs.map +1 -0
- package/dist/production/src/lib/tenant/tenantConfig.js +5 -0
- package/dist/production/src/lib/tenant/tenantConfig.js.map +1 -0
- package/dist/production/src/lib/transfer/DataTransferClient.cjs.map +1 -1
- package/dist/production/src/lib/transfer/DataTransferClient.js.map +1 -1
- package/dist/production/src/lib/workspace/WorkspaceResolver.cjs +6 -6
- package/dist/production/src/lib/workspace/WorkspaceResolver.cjs.map +1 -1
- package/dist/production/src/lib/workspace/WorkspaceResolver.js.map +1 -1
- package/dist/types/commands/actions/ActionsGetEventCommand.d.ts +1 -1
- package/dist/types/commands/actions/ActionsGetEventCommand.d.ts.map +1 -1
- package/dist/types/commands/actions/ActionsListFailedEventsCommand.d.ts +1 -1
- package/dist/types/commands/actions/ActionsListFailedEventsCommand.d.ts.map +1 -1
- package/dist/types/commands/actions/ActionsListVariablesCommand.d.ts +1 -1
- package/dist/types/commands/actions/ActionsListVariablesCommand.d.ts.map +1 -1
- package/dist/types/commands/actions/ActionsRetryEventCommand.d.ts +1 -1
- package/dist/types/commands/actions/ActionsRetryEventCommand.d.ts.map +1 -1
- package/dist/types/commands/actions/ActionsSetVariablesCommand.d.ts +1 -1
- package/dist/types/commands/actions/ActionsSetVariablesCommand.d.ts.map +1 -1
- package/dist/types/commands/actions/ActionsStopEventCommand.d.ts +1 -1
- package/dist/types/commands/actions/ActionsStopEventCommand.d.ts.map +1 -1
- package/dist/types/commands/deploy/DeployCommand.d.ts +7 -6
- package/dist/types/commands/deploy/DeployCommand.d.ts.map +1 -1
- package/dist/types/commands/deploy/index.d.ts +1 -1
- package/dist/types/commands/deploy/index.d.ts.map +1 -1
- package/dist/types/commands/index.d.ts +6 -5
- package/dist/types/commands/index.d.ts.map +1 -1
- package/dist/types/commands/migrations/MigrationAmendCommand.d.ts +8 -7
- package/dist/types/commands/migrations/MigrationAmendCommand.d.ts.map +1 -1
- package/dist/types/commands/migrations/MigrationDescribeCommand.d.ts +1 -1
- package/dist/types/commands/migrations/MigrationDescribeCommand.d.ts.map +1 -1
- package/dist/types/commands/migrations/MigrationDiffCommand.d.ts +8 -5
- package/dist/types/commands/migrations/MigrationDiffCommand.d.ts.map +1 -1
- package/dist/types/commands/migrations/MigrationExecuteCommand.d.ts +2 -1
- package/dist/types/commands/migrations/MigrationExecuteCommand.d.ts.map +1 -1
- package/dist/types/commands/migrations/MigrationInitStateCommand.d.ts +14 -0
- package/dist/types/commands/migrations/MigrationInitStateCommand.d.ts.map +1 -0
- package/dist/types/commands/migrations/MigrationRebaseCommand.d.ts +1 -1
- package/dist/types/commands/migrations/MigrationRebaseCommand.d.ts.map +1 -1
- package/dist/types/commands/migrations/MigrationSnapshotCommand.d.ts +12 -0
- package/dist/types/commands/migrations/MigrationSnapshotCommand.d.ts.map +1 -0
- package/dist/types/commands/migrations/MigrationStatusCommand.d.ts +3 -3
- package/dist/types/commands/migrations/MigrationStatusCommand.d.ts.map +1 -1
- package/dist/types/commands/migrations/MigrationVerifySnapshotCommand.d.ts +12 -0
- package/dist/types/commands/migrations/MigrationVerifySnapshotCommand.d.ts.map +1 -0
- package/dist/types/commands/migrations/index.d.ts +10 -7
- package/dist/types/commands/migrations/index.d.ts.map +1 -1
- package/dist/types/commands/misc/index.d.ts +1 -1
- package/dist/types/commands/misc/index.d.ts.map +1 -1
- package/dist/types/commands/project/ProjectGenerateDocumentationCommand.d.ts +1 -1
- package/dist/types/commands/project/ProjectGenerateDocumentationCommand.d.ts.map +1 -1
- package/dist/types/commands/project/ProjectPrintSchemaCommand.d.ts +1 -1
- package/dist/types/commands/project/ProjectPrintSchemaCommand.d.ts.map +1 -1
- package/dist/types/commands/project/ProjectValidateCommand.d.ts +2 -2
- package/dist/types/commands/project/ProjectValidateCommand.d.ts.map +1 -1
- package/dist/types/commands/project/index.d.ts +3 -3
- package/dist/types/commands/project/index.d.ts.map +1 -1
- package/dist/types/commands/tenant/TenantApplyCommand.d.ts +21 -0
- package/dist/types/commands/tenant/TenantApplyCommand.d.ts.map +1 -0
- package/dist/types/commands/tenant/index.d.ts +2 -0
- package/dist/types/commands/tenant/index.d.ts.map +1 -0
- package/dist/types/commands/transfer/ExportCommand.d.ts +2 -2
- package/dist/types/commands/transfer/ExportCommand.d.ts.map +1 -1
- package/dist/types/commands/transfer/ImportCommand.d.ts +2 -2
- package/dist/types/commands/transfer/ImportCommand.d.ts.map +1 -1
- package/dist/types/commands/transfer/TransferCommand.d.ts +2 -2
- package/dist/types/commands/transfer/TransferCommand.d.ts.map +1 -1
- package/dist/types/commands/transfer/index.d.ts +3 -3
- package/dist/types/commands/transfer/index.d.ts.map +1 -1
- package/dist/types/commands/workspace/WorkspaceUpdateApiCommand.d.ts +1 -1
- package/dist/types/commands/workspace/WorkspaceUpdateApiCommand.d.ts.map +1 -1
- package/dist/types/commands/workspace/index.d.ts +1 -1
- package/dist/types/commands/workspace/index.d.ts.map +1 -1
- package/dist/types/dic.d.ts +54 -32
- package/dist/types/dic.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/lib/SystemClientProvider.d.ts +1 -1
- package/dist/types/lib/SystemClientProvider.d.ts.map +1 -1
- package/dist/types/lib/TenantClientProvider.d.ts +2 -2
- package/dist/types/lib/TenantClientProvider.d.ts.map +1 -1
- package/dist/types/lib/VersionChecker.d.ts +1 -1
- package/dist/types/lib/VersionChecker.d.ts.map +1 -1
- package/dist/types/lib/admin/AdminClient.d.ts +1 -1
- package/dist/types/lib/admin/AdminClient.d.ts.map +1 -1
- package/dist/types/lib/admin/AdminDeployer.d.ts +3 -3
- package/dist/types/lib/admin/AdminDeployer.d.ts.map +1 -1
- package/dist/types/lib/fs/DockerComposeManager.d.ts +2 -2
- package/dist/types/lib/fs/DockerComposeManager.d.ts.map +1 -1
- package/dist/types/lib/fs/YamlHandler.d.ts +2 -2
- package/dist/types/lib/fs/YamlHandler.d.ts.map +1 -1
- package/dist/types/lib/js/EsBuildBuilder.d.ts +1 -1
- package/dist/types/lib/js/EsBuildBuilder.d.ts.map +1 -1
- package/dist/types/lib/js/EvalExecutor.d.ts +1 -1
- package/dist/types/lib/js/EvalExecutor.d.ts.map +1 -1
- package/dist/types/lib/js/JsCodeRunner.d.ts +2 -2
- package/dist/types/lib/js/JsCodeRunner.d.ts.map +1 -1
- package/dist/types/lib/migrations/MigrationExecutionFacade.d.ts +13 -8
- package/dist/types/lib/migrations/MigrationExecutionFacade.d.ts.map +1 -1
- package/dist/types/lib/migrations/MigrationRebaseFacade.d.ts +5 -4
- package/dist/types/lib/migrations/MigrationRebaseFacade.d.ts.map +1 -1
- package/dist/types/lib/migrations/MigrationSnapshotFacade.d.ts +28 -0
- package/dist/types/lib/migrations/MigrationSnapshotFacade.d.ts.map +1 -0
- package/dist/types/lib/migrations/MigrationsStatusFacade.d.ts +2 -2
- package/dist/types/lib/migrations/MigrationsStatusFacade.d.ts.map +1 -1
- package/dist/types/lib/project/RemoteProjectProvider.d.ts +1 -1
- package/dist/types/lib/project/RemoteProjectProvider.d.ts.map +1 -1
- package/dist/types/lib/project/RemoteProjectResolver.d.ts +2 -2
- package/dist/types/lib/project/RemoteProjectResolver.d.ts.map +1 -1
- package/dist/types/lib/project/docs/components/EntityInfo.d.ts +1 -1
- package/dist/types/lib/project/docs/components/EntityInfo.d.ts.map +1 -1
- package/dist/types/lib/project/docs/components/OnDelete.d.ts +1 -1
- package/dist/types/lib/project/docs/components/OnDelete.d.ts.map +1 -1
- package/dist/types/lib/schema/SchemaLoader.d.ts +2 -2
- package/dist/types/lib/schema/SchemaLoader.d.ts.map +1 -1
- package/dist/types/lib/tenant/TenantClient.d.ts +15 -0
- package/dist/types/lib/tenant/TenantClient.d.ts.map +1 -1
- package/dist/types/lib/tenant/TenantConfigApplier.d.ts +18 -0
- package/dist/types/lib/tenant/TenantConfigApplier.d.ts.map +1 -0
- package/dist/types/lib/tenant/TenantConfigLoader.d.ts +16 -0
- package/dist/types/lib/tenant/TenantConfigLoader.d.ts.map +1 -0
- package/dist/types/lib/tenant/tenantConfig.d.ts +74 -0
- package/dist/types/lib/tenant/tenantConfig.d.ts.map +1 -0
- package/dist/types/lib/transfer/DataTransferClient.d.ts +1 -1
- package/dist/types/lib/transfer/DataTransferClient.d.ts.map +1 -1
- package/dist/types/lib/workspace/WorkspaceResolver.d.ts +2 -2
- package/dist/types/lib/workspace/WorkspaceResolver.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +33 -15
- package/src/commands/actions/ActionsGetEventCommand.ts +2 -2
- package/src/commands/actions/ActionsListFailedEventsCommand.ts +2 -2
- package/src/commands/actions/ActionsListVariablesCommand.ts +2 -2
- package/src/commands/actions/ActionsRetryEventCommand.ts +2 -2
- package/src/commands/actions/ActionsSetVariablesCommand.ts +2 -2
- package/src/commands/actions/ActionsStopEventCommand.ts +2 -2
- package/src/commands/deploy/DeployCommand.ts +13 -8
- package/src/commands/deploy/index.ts +1 -1
- package/src/commands/index.ts +6 -5
- package/src/commands/migrations/MigrationAmendCommand.ts +38 -10
- package/src/commands/migrations/MigrationDescribeCommand.ts +1 -1
- package/src/commands/migrations/MigrationDiffCommand.ts +50 -6
- package/src/commands/migrations/MigrationExecuteCommand.ts +6 -1
- package/src/commands/migrations/MigrationInitStateCommand.ts +34 -0
- package/src/commands/migrations/MigrationRebaseCommand.ts +1 -1
- package/src/commands/migrations/MigrationSnapshotCommand.ts +34 -0
- package/src/commands/migrations/MigrationStatusCommand.ts +3 -3
- package/src/commands/migrations/MigrationVerifySnapshotCommand.ts +28 -0
- package/src/commands/migrations/index.ts +10 -7
- package/src/commands/misc/index.ts +1 -1
- package/src/commands/project/ProjectGenerateDocumentationCommand.ts +3 -3
- package/src/commands/project/ProjectPrintSchemaCommand.ts +2 -2
- package/src/commands/project/ProjectValidateCommand.ts +3 -3
- package/src/commands/project/index.ts +3 -3
- package/src/commands/tenant/TenantApplyCommand.ts +57 -0
- package/src/commands/tenant/index.ts +1 -0
- package/src/commands/transfer/ExportCommand.ts +4 -4
- package/src/commands/transfer/ImportCommand.ts +6 -6
- package/src/commands/transfer/TransferCommand.ts +6 -6
- package/src/commands/transfer/index.ts +3 -3
- package/src/commands/workspace/WorkspaceUpdateApiCommand.ts +2 -2
- package/src/commands/workspace/index.ts +1 -1
- package/src/dic.ts +103 -37
- package/src/index.ts +1 -0
- package/src/lib/SystemClientProvider.ts +1 -1
- package/src/lib/TenantClientProvider.ts +2 -2
- package/src/lib/VersionChecker.ts +2 -2
- package/src/lib/admin/AdminClient.ts +2 -2
- package/src/lib/admin/AdminDeployer.ts +3 -3
- package/src/lib/fs/DockerComposeManager.ts +2 -2
- package/src/lib/fs/YamlHandler.ts +2 -2
- package/src/lib/js/EsBuildBuilder.ts +1 -1
- package/src/lib/js/EvalExecutor.ts +1 -1
- package/src/lib/js/JsCodeRunner.ts +2 -2
- package/src/lib/migrations/MigrationExecutionFacade.ts +117 -23
- package/src/lib/migrations/MigrationPrinter.ts +1 -1
- package/src/lib/migrations/MigrationRebaseFacade.ts +10 -3
- package/src/lib/migrations/MigrationSnapshotFacade.ts +218 -0
- package/src/lib/migrations/MigrationsStatusFacade.ts +2 -2
- package/src/lib/migrations/MigrationsValidator.ts +1 -1
- package/src/lib/project/RemoteProjectProvider.ts +1 -1
- package/src/lib/project/RemoteProjectResolver.ts +3 -3
- package/src/lib/project/docs/components/EntityInfo.tsx +6 -6
- package/src/lib/project/docs/components/EntityLink.tsx +1 -1
- package/src/lib/project/docs/components/FieldLink.tsx +2 -2
- package/src/lib/project/docs/components/FieldPermissions.tsx +1 -1
- package/src/lib/project/docs/components/FieldType.tsx +2 -2
- package/src/lib/project/docs/components/OnDelete.tsx +3 -3
- package/src/lib/project/docs/components/ProjectInfo.tsx +3 -3
- package/src/lib/project/docs/projectDescribe.tsx +2 -2
- package/src/lib/schema/SchemaLoader.ts +2 -2
- package/src/lib/schema/SchemaValidationHelper.ts +1 -1
- package/src/lib/tenant/TenantClient.ts +123 -14
- package/src/lib/tenant/TenantConfigApplier.ts +72 -0
- package/src/lib/tenant/TenantConfigLoader.ts +41 -0
- package/src/lib/tenant/tenantConfig.ts +101 -0
- package/src/lib/transfer/DataTransferClient.ts +2 -2
- package/src/lib/workspace/WorkspaceResolver.ts +2 -2
- package/src/run.ts +6 -6
- package/src/tsconfig.json +1 -0
- package/tenant.config.example.ts +64 -0
- package/tests/cases/unit/MigrationAmendCommand.test.ts +156 -0
- package/tests/cases/unit/MigrationExecutionFacade.test.ts +81 -0
- package/tests/cases/unit/MigrationRebaseFacade.test.ts +87 -0
- package/tests/cases/unit/MigrationSnapshotFacade.test.ts +243 -0
- package/tests/tenantConfigApplier.test.ts +87 -0
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
import { GraphQlClient } from '@contember/graphql-client'
|
|
2
|
+
import {
|
|
3
|
+
addIDPError$$,
|
|
4
|
+
addIDPResponse$$,
|
|
5
|
+
addMailTemplateError$$,
|
|
6
|
+
addMailTemplateResponse$$,
|
|
7
|
+
type ConfigInput,
|
|
8
|
+
configureError$$,
|
|
9
|
+
configureResponse$$,
|
|
10
|
+
createProjectResponse$$,
|
|
11
|
+
createProjectResponseError$$,
|
|
12
|
+
disableIDPError$$,
|
|
13
|
+
disableIDPResponse$$,
|
|
14
|
+
enableIDPError$$,
|
|
15
|
+
enableIDPResponse$$,
|
|
16
|
+
identityProvider$,
|
|
17
|
+
type MailTemplate,
|
|
18
|
+
mutation$,
|
|
19
|
+
query$,
|
|
20
|
+
updateIDPError$$,
|
|
21
|
+
updateIDPResponse$$,
|
|
22
|
+
} from '@contember/graphql-client-tenant'
|
|
23
|
+
import { Fetcher, TextWriter, util } from 'graphql-ts-client-api'
|
|
24
|
+
import { TenantGlobalConfig, TenantIdpOptions, TenantMailTemplate } from './tenantConfig.js'
|
|
2
25
|
|
|
3
26
|
export const createTenantApiUrl = (url: string) => {
|
|
4
27
|
if (url.endsWith('/')) {
|
|
@@ -10,6 +33,27 @@ export const createTenantApiUrl = (url: string) => {
|
|
|
10
33
|
return url + '/tenant'
|
|
11
34
|
}
|
|
12
35
|
|
|
36
|
+
export interface RemoteIdentityProvider {
|
|
37
|
+
slug: string
|
|
38
|
+
type: string
|
|
39
|
+
disabledAt: string | null
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface MutationResult {
|
|
43
|
+
ok: boolean
|
|
44
|
+
error?: { code: string; developerMessage?: string } | null
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Fetchers are immutable and reusable, so they are built once at module load.
|
|
48
|
+
const createProjectFetcher = mutation$.createProject(createProjectResponse$$.error(createProjectResponseError$$))
|
|
49
|
+
const configureFetcher = mutation$.configure(configureResponse$$.error(configureError$$))
|
|
50
|
+
const identityProvidersFetcher = query$.identityProviders(identityProvider$.slug.type.disabledAt)
|
|
51
|
+
const addIdpFetcher = mutation$.addIDP(addIDPResponse$$.error(addIDPError$$))
|
|
52
|
+
const updateIdpFetcher = mutation$.updateIDP(updateIDPResponse$$.error(updateIDPError$$))
|
|
53
|
+
const enableIdpFetcher = mutation$.enableIDP(enableIDPResponse$$.error(enableIDPError$$))
|
|
54
|
+
const disableIdpFetcher = mutation$.disableIDP(disableIDPResponse$$.error(disableIDPError$$))
|
|
55
|
+
const addMailTemplateFetcher = mutation$.addMailTemplate(addMailTemplateResponse$$.error(addMailTemplateError$$))
|
|
56
|
+
|
|
13
57
|
export class TenantClient {
|
|
14
58
|
constructor(private readonly apiClient: GraphQlClient) {}
|
|
15
59
|
|
|
@@ -19,22 +63,87 @@ export class TenantClient {
|
|
|
19
63
|
}
|
|
20
64
|
|
|
21
65
|
public async createProject(slug: string, ignoreExisting = false): Promise<void> {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
code
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}`
|
|
30
|
-
const result = await this.apiClient.execute<{
|
|
31
|
-
createProject: { ok: boolean; error: { code: string } }
|
|
32
|
-
}>(query, { variables: { slug } })
|
|
33
|
-
if (!result.createProject.ok) {
|
|
34
|
-
if (ignoreExisting && result.createProject.error.code === 'ALREADY_EXISTS') {
|
|
66
|
+
const result = await this.exec(createProjectFetcher, { projectSlug: slug })
|
|
67
|
+
if (!result.createProject?.ok) {
|
|
68
|
+
const code = result.createProject?.error?.code
|
|
69
|
+
if (ignoreExisting && code === 'ALREADY_EXISTS') {
|
|
35
70
|
return
|
|
36
71
|
}
|
|
37
|
-
throw
|
|
72
|
+
throw code ?? 'UNKNOWN'
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public async configure(config: TenantGlobalConfig): Promise<void> {
|
|
77
|
+
// `TenantGlobalConfig` widens a few fields to `| null` (the API accepts an
|
|
78
|
+
// explicit null to clear/disable); the generated wire type omits that.
|
|
79
|
+
const result = await this.exec(configureFetcher, { config: config as ConfigInput })
|
|
80
|
+
this.assertOk(result.configure, 'configure')
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public async listIdentityProviders(): Promise<RemoteIdentityProvider[]> {
|
|
84
|
+
const result = await this.exec(identityProvidersFetcher, {})
|
|
85
|
+
return result.identityProviders.map(it => ({
|
|
86
|
+
slug: it.slug,
|
|
87
|
+
type: it.type,
|
|
88
|
+
disabledAt: it.disabledAt ?? null,
|
|
89
|
+
}))
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public async addIdp(slug: string, type: string, configuration: unknown, options?: TenantIdpOptions): Promise<void> {
|
|
93
|
+
const result = await this.exec(addIdpFetcher, { identityProvider: slug, type, configuration, options })
|
|
94
|
+
this.assertOk(result.addIDP, `addIDP(${slug})`)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public async updateIdp(slug: string, type: string, configuration: unknown, options?: TenantIdpOptions): Promise<void> {
|
|
98
|
+
const result = await this.exec(updateIdpFetcher, {
|
|
99
|
+
identityProvider: slug,
|
|
100
|
+
type,
|
|
101
|
+
configuration,
|
|
102
|
+
options,
|
|
103
|
+
mergeConfiguration: false,
|
|
104
|
+
})
|
|
105
|
+
this.assertOk(result.updateIDP, `updateIDP(${slug})`)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public async enableIdp(slug: string): Promise<void> {
|
|
109
|
+
const result = await this.exec(enableIdpFetcher, { identityProvider: slug })
|
|
110
|
+
this.assertOk(result.enableIDP, `enableIDP(${slug})`)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public async disableIdp(slug: string): Promise<void> {
|
|
114
|
+
const result = await this.exec(disableIdpFetcher, { identityProvider: slug })
|
|
115
|
+
this.assertOk(result.disableIDP, `disableIDP(${slug})`)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public async addMailTemplate(template: TenantMailTemplate): Promise<void> {
|
|
119
|
+
const result = await this.exec(addMailTemplateFetcher, { template: template as MailTemplate })
|
|
120
|
+
this.assertOk(result.addMailTemplate, `addMailTemplate(${template.type}/${template.variant ?? ''})`)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private async exec<TData extends object, TVariables extends object>(
|
|
124
|
+
fetcher: Fetcher<'Query' | 'Mutation', TData, TVariables>,
|
|
125
|
+
variables: TVariables,
|
|
126
|
+
): Promise<TData> {
|
|
127
|
+
const writer = new TextWriter()
|
|
128
|
+
writer.text(fetcher.fetchableType.name.toLowerCase())
|
|
129
|
+
if (fetcher.variableTypeMap.size !== 0) {
|
|
130
|
+
writer.scope({ type: 'ARGUMENTS', multiLines: fetcher.variableTypeMap.size > 2, suffix: ' ' }, () => {
|
|
131
|
+
util.iterateMap(fetcher.variableTypeMap, ([name, type]) => {
|
|
132
|
+
writer.seperator()
|
|
133
|
+
writer.text(`$${name}: ${type}`)
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
writer.text(fetcher.toString())
|
|
138
|
+
writer.text(fetcher.toFragmentString())
|
|
139
|
+
return this.apiClient.execute<TData>(writer.toString(), { variables })
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private assertOk(result: MutationResult | undefined, operation: string): void {
|
|
143
|
+
if (!result?.ok) {
|
|
144
|
+
const code = result?.error?.code ?? 'UNKNOWN'
|
|
145
|
+
const message = result?.error?.developerMessage
|
|
146
|
+
throw `${operation} failed: ${code}${message ? ` — ${message}` : ''}`
|
|
38
147
|
}
|
|
39
148
|
}
|
|
40
149
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { TenantClient } from './TenantClient.js'
|
|
2
|
+
import { TenantConfig } from './tenantConfig.js'
|
|
3
|
+
|
|
4
|
+
export interface TenantConfigApplyOptions {
|
|
5
|
+
dryRun?: boolean
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Applies a {@link TenantConfig} to a tenant idempotently:
|
|
10
|
+
* - `configure` is a partial merge, so it is always (re)sent.
|
|
11
|
+
* - identity providers are added or updated based on the current state, then
|
|
12
|
+
* enabled/disabled to match `disabled`.
|
|
13
|
+
* - mail templates are upserted server-side by `addMailTemplate`.
|
|
14
|
+
*
|
|
15
|
+
* Nothing is ever removed — entries missing from the config are left untouched.
|
|
16
|
+
*/
|
|
17
|
+
export class TenantConfigApplier {
|
|
18
|
+
public async apply(client: TenantClient, config: TenantConfig, options: TenantConfigApplyOptions = {}): Promise<void> {
|
|
19
|
+
const dryRun = options.dryRun === true
|
|
20
|
+
const log = (message: string) => console.log(`${dryRun ? '[dry-run] ' : ''}${message}`)
|
|
21
|
+
|
|
22
|
+
if (config.config) {
|
|
23
|
+
log('configure: applying global tenant config')
|
|
24
|
+
if (!dryRun) {
|
|
25
|
+
await client.configure(config.config)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (config.identityProviders && Object.keys(config.identityProviders).length > 0) {
|
|
30
|
+
const existing = await client.listIdentityProviders()
|
|
31
|
+
const existingBySlug = new Map(existing.map(it => [it.slug, it]))
|
|
32
|
+
|
|
33
|
+
for (const [slug, idp] of Object.entries(config.identityProviders)) {
|
|
34
|
+
const current = existingBySlug.get(slug)
|
|
35
|
+
if (!current) {
|
|
36
|
+
log(`addIDP: ${slug} (${idp.type})`)
|
|
37
|
+
if (!dryRun) {
|
|
38
|
+
await client.addIdp(slug, idp.type, idp.configuration, idp.options)
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
log(`updateIDP: ${slug} (${idp.type})`)
|
|
42
|
+
if (!dryRun) {
|
|
43
|
+
await client.updateIdp(slug, idp.type, idp.configuration, idp.options)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const wantDisabled = idp.disabled === true
|
|
48
|
+
const isDisabled = current ? current.disabledAt !== null : false
|
|
49
|
+
if (wantDisabled && !isDisabled) {
|
|
50
|
+
log(`disableIDP: ${slug}`)
|
|
51
|
+
if (!dryRun) {
|
|
52
|
+
await client.disableIdp(slug)
|
|
53
|
+
}
|
|
54
|
+
} else if (!wantDisabled && isDisabled) {
|
|
55
|
+
log(`enableIDP: ${slug}`)
|
|
56
|
+
if (!dryRun) {
|
|
57
|
+
await client.enableIdp(slug)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (config.mailTemplates && config.mailTemplates.length > 0) {
|
|
64
|
+
for (const template of config.mailTemplates) {
|
|
65
|
+
log(`addMailTemplate: ${template.type}${template.variant ? `/${template.variant}` : ''}`)
|
|
66
|
+
if (!dryRun) {
|
|
67
|
+
await client.addMailTemplate(template)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { isAbsolute, resolve } from 'node:path'
|
|
2
|
+
import { JsCodeRunner } from '../js/JsCodeRunner.js'
|
|
3
|
+
import { TenantConfig } from './tenantConfig.js'
|
|
4
|
+
|
|
5
|
+
const resolvePath = (path: string): string => isAbsolute(path) ? path : resolve(process.cwd(), path)
|
|
6
|
+
|
|
7
|
+
const extractDefault = (result: unknown): TenantConfig => {
|
|
8
|
+
if (typeof result !== 'object' || result === null || !('default' in result)) {
|
|
9
|
+
throw `Tenant config file must have a default export (use \`export default defineTenantConfig({ ... })\`).`
|
|
10
|
+
}
|
|
11
|
+
const config = (result as { default: unknown }).default
|
|
12
|
+
if (typeof config !== 'object' || config === null) {
|
|
13
|
+
throw `Default export of the tenant config file must be an object.`
|
|
14
|
+
}
|
|
15
|
+
return config as TenantConfig
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface TenantConfigLoader {
|
|
19
|
+
loadConfig(path: string): Promise<TenantConfig>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Loads a `tenant.config.ts` directly via dynamic import (Bun runtime). */
|
|
23
|
+
export class ImportTenantConfigLoader implements TenantConfigLoader {
|
|
24
|
+
async loadConfig(path: string): Promise<TenantConfig> {
|
|
25
|
+
const result = await import(resolvePath(path))
|
|
26
|
+
return extractDefault(result)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Loads a `tenant.config.ts` by transpiling it first (Node runtime). */
|
|
31
|
+
export class TranspilingTenantConfigLoader implements TenantConfigLoader {
|
|
32
|
+
constructor(
|
|
33
|
+
private readonly jsCodeRunner: JsCodeRunner,
|
|
34
|
+
) {
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async loadConfig(path: string): Promise<TenantConfig> {
|
|
38
|
+
const result = await this.jsCodeRunner.run(resolvePath(path))
|
|
39
|
+
return extractDefault(result)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ConfigCaptchaInput,
|
|
3
|
+
ConfigInput,
|
|
4
|
+
ConfigLoginInput,
|
|
5
|
+
ConfigPasswordInput,
|
|
6
|
+
ConfigPasswordlessInput,
|
|
7
|
+
ConfigRateLimitsInput,
|
|
8
|
+
ConfigRateLimitWindowInput,
|
|
9
|
+
IDPOptions,
|
|
10
|
+
MailTemplate,
|
|
11
|
+
} from '@contember/graphql-client-tenant'
|
|
12
|
+
|
|
13
|
+
// Enums and leaf input shapes are re-derived from the generated tenant client
|
|
14
|
+
// (`@contember/graphql-client-tenant`, generated from `tenant.graphql`), so they
|
|
15
|
+
// stay in sync with the schema. The only thing layered on top is `| null` on the
|
|
16
|
+
// fields where the API treats an explicit `null`/`''` as "clear/disable" — the
|
|
17
|
+
// codegen renders nullable inputs as optional only and drops the `| null`.
|
|
18
|
+
export type { CaptchaProvider, ConfigPolicy, MailType } from '@contember/graphql-client-tenant'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* ISO 8601 duration string, e.g. `"P1D"` (1 day) or `"PT5M"` (5 minutes).
|
|
22
|
+
*/
|
|
23
|
+
export type Interval = string
|
|
24
|
+
|
|
25
|
+
/** Adds `| null` to the given keys of an otherwise non-nullable generated input. */
|
|
26
|
+
type WithNullable<T, K extends keyof T> = Omit<T, K> & { readonly [P in K]?: T[P] | null }
|
|
27
|
+
|
|
28
|
+
export type TenantPasswordConfig = WithNullable<ConfigPasswordInput, 'pattern'>
|
|
29
|
+
|
|
30
|
+
export type TenantLoginConfig = WithNullable<ConfigLoginInput, 'maxTokenExpiration'>
|
|
31
|
+
|
|
32
|
+
export type TenantPasswordlessConfig = WithNullable<ConfigPasswordlessInput, 'url'>
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* `provider: null` disables captcha verification.
|
|
36
|
+
* `secret` is write-only: `null`/omitted leaves the stored value unchanged, `''` clears it.
|
|
37
|
+
*/
|
|
38
|
+
export type TenantCaptchaConfig = WithNullable<ConfigCaptchaInput, 'provider' | 'secret' | 'threshold'>
|
|
39
|
+
|
|
40
|
+
export type TenantRateLimitWindow = ConfigRateLimitWindowInput
|
|
41
|
+
|
|
42
|
+
export type TenantRateLimitsConfig = ConfigRateLimitsInput
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Maps to the tenant `configure(config: ConfigInput!)` mutation. New config
|
|
46
|
+
* groups added to the schema flow through automatically; only the groups that
|
|
47
|
+
* need `| null` overrides are pinned.
|
|
48
|
+
*/
|
|
49
|
+
export type TenantGlobalConfig = Omit<ConfigInput, 'password' | 'login' | 'passwordless' | 'captcha'> & {
|
|
50
|
+
readonly password?: TenantPasswordConfig
|
|
51
|
+
readonly login?: TenantLoginConfig
|
|
52
|
+
readonly passwordless?: TenantPasswordlessConfig
|
|
53
|
+
readonly captcha?: TenantCaptchaConfig
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type TenantIdpOptions = IDPOptions
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* A single identity provider. The record key is used as the provider slug.
|
|
60
|
+
* `type` is the handler key registered on the server (built-in: `oidc`,
|
|
61
|
+
* `facebook`, `apple`).
|
|
62
|
+
*
|
|
63
|
+
* This is a CLI-specific composite — the `addIDP`/`updateIDP` mutations take
|
|
64
|
+
* `type`/`configuration`/`options` as separate arguments, not a single input.
|
|
65
|
+
*/
|
|
66
|
+
export interface TenantIdpConfig {
|
|
67
|
+
type: string
|
|
68
|
+
configuration: Record<string, unknown>
|
|
69
|
+
options?: TenantIdpOptions
|
|
70
|
+
/** When `true`, the provider is disabled (kept, but not usable for sign-in). */
|
|
71
|
+
disabled?: boolean
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Maps to the `addMailTemplate(template: MailTemplate!)` mutation. */
|
|
75
|
+
export type TenantMailTemplate = WithNullable<MailTemplate, 'projectSlug' | 'replyTo'>
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Declarative tenant configuration. Applied idempotently by
|
|
79
|
+
* `contember tenant:apply`.
|
|
80
|
+
*/
|
|
81
|
+
export interface TenantConfig {
|
|
82
|
+
config?: TenantGlobalConfig
|
|
83
|
+
/** Identity providers keyed by slug. */
|
|
84
|
+
identityProviders?: Record<string, TenantIdpConfig>
|
|
85
|
+
mailTemplates?: TenantMailTemplate[]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Type-safe helper for authoring a `tenant.config.ts`. Returns the config
|
|
90
|
+
* unchanged — it exists only to provide editor autocompletion and type
|
|
91
|
+
* checking.
|
|
92
|
+
*
|
|
93
|
+
* ```ts
|
|
94
|
+
* import { defineTenantConfig } from '@contember/cli'
|
|
95
|
+
*
|
|
96
|
+
* export default defineTenantConfig({
|
|
97
|
+
* config: { password: { minLength: 8 } },
|
|
98
|
+
* })
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export const defineTenantConfig = (config: TenantConfig): TenantConfig => config
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { LineTransform } from '../stream'
|
|
1
|
+
import { LineTransform } from '../stream.js'
|
|
2
2
|
import { Readable } from 'node:stream'
|
|
3
3
|
import { createGzip } from 'node:zlib'
|
|
4
|
-
import { RemoteProject } from '../project/RemoteProject'
|
|
4
|
+
import { RemoteProject } from '../project/RemoteProject.js'
|
|
5
5
|
|
|
6
6
|
export class DataTransferClient {
|
|
7
7
|
dataImport = async ({ printProgress, stream, project, gzip }: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Workspace } from './Workspace'
|
|
1
|
+
import { Workspace } from './Workspace.js'
|
|
2
2
|
import { join, resolve } from 'node:path'
|
|
3
|
-
import { YamlHandler } from '../fs/YamlHandler'
|
|
3
|
+
import { YamlHandler } from '../fs/YamlHandler.js'
|
|
4
4
|
|
|
5
5
|
export interface LocalProjectConfig {
|
|
6
6
|
apiDir?: string
|
package/src/run.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { join, resolve } from 'node:path'
|
|
3
|
-
import { packageRoot } from './consts'
|
|
4
|
-
import { createContainer } from './dic'
|
|
5
|
-
import { readCliEnv } from './lib/env'
|
|
6
|
-
import { WorkspaceResolver } from './lib/workspace/WorkspaceResolver'
|
|
7
|
-
import { YamlHandler } from './lib/fs/YamlHandler'
|
|
8
|
-
import { FileSystem } from './lib/fs/FileSystem'
|
|
3
|
+
import { packageRoot } from './consts.js'
|
|
4
|
+
import { createContainer } from './dic.js'
|
|
5
|
+
import { readCliEnv } from './lib/env.js'
|
|
6
|
+
import { WorkspaceResolver } from './lib/workspace/WorkspaceResolver.js'
|
|
7
|
+
import { YamlHandler } from './lib/fs/YamlHandler.js'
|
|
8
|
+
import { FileSystem } from './lib/fs/FileSystem.js'
|
|
9
9
|
;(async () => {
|
|
10
10
|
const version = require(join(packageRoot, 'package.json')).version
|
|
11
11
|
const nodeVersion = process.version.match(/^v?(\d+)\..+$/)
|
package/src/tsconfig.json
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
{ "path": "../../database/src" },
|
|
14
14
|
{ "path": "../../dic/src" },
|
|
15
15
|
{ "path": "../../graphql-client/src" },
|
|
16
|
+
{ "path": "../../graphql-client-tenant/src" },
|
|
16
17
|
{ "path": "../../engine-content-api/src" },
|
|
17
18
|
{ "path": "../../engine-common/src" },
|
|
18
19
|
{ "path": "../../schema/src" },
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { defineTenantConfig } from '@contember/cli'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Example tenant configuration. Copy to `tenant.config.ts` and run:
|
|
5
|
+
*
|
|
6
|
+
* contember tenant:apply --dsn "contember://app:TOKEN@api.example.com"
|
|
7
|
+
* contember tenant:apply tenant.config.ts --dry-run
|
|
8
|
+
*
|
|
9
|
+
* The token must have PROJECT_ADMIN/SUPER_ADMIN privileges (a deploy-only
|
|
10
|
+
* token is not sufficient). Applying is idempotent and never removes entries.
|
|
11
|
+
*/
|
|
12
|
+
export default defineTenantConfig({
|
|
13
|
+
config: {
|
|
14
|
+
password: {
|
|
15
|
+
minLength: 8,
|
|
16
|
+
requireUppercase: 1,
|
|
17
|
+
requireLowercase: 1,
|
|
18
|
+
requireDigit: 1,
|
|
19
|
+
checkHibp: true,
|
|
20
|
+
},
|
|
21
|
+
login: {
|
|
22
|
+
defaultTokenExpiration: 'P1D',
|
|
23
|
+
maxTokenExpiration: 'P2D',
|
|
24
|
+
revealUserExists: false,
|
|
25
|
+
},
|
|
26
|
+
passwordless: {
|
|
27
|
+
enabled: 'optIn',
|
|
28
|
+
expiration: 'PT5M',
|
|
29
|
+
},
|
|
30
|
+
captcha: {
|
|
31
|
+
provider: 'turnstile',
|
|
32
|
+
secret: process.env.TURNSTILE_SECRET,
|
|
33
|
+
threshold: 0.5,
|
|
34
|
+
},
|
|
35
|
+
rateLimits: {
|
|
36
|
+
loginPerIp: { limit: 10, window: 'PT1M' },
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
identityProviders: {
|
|
41
|
+
google: {
|
|
42
|
+
type: 'oidc',
|
|
43
|
+
configuration: {
|
|
44
|
+
clientId: process.env.GOOGLE_CLIENT_ID,
|
|
45
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
|
46
|
+
url: 'https://accounts.google.com',
|
|
47
|
+
},
|
|
48
|
+
options: {
|
|
49
|
+
autoSignUp: true,
|
|
50
|
+
exclusive: false,
|
|
51
|
+
},
|
|
52
|
+
disabled: false,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
mailTemplates: [
|
|
57
|
+
{
|
|
58
|
+
type: 'RESET_PASSWORD_REQUEST',
|
|
59
|
+
variant: 'cs',
|
|
60
|
+
subject: 'Obnovení hesla',
|
|
61
|
+
content: 'Klikněte na odkaz pro obnovení hesla: {{link}}',
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
})
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
|
|
2
|
+
import * as fs from 'node:fs/promises'
|
|
3
|
+
import * as os from 'node:os'
|
|
4
|
+
import * as path from 'node:path'
|
|
5
|
+
import { c, createSchema } from '@contember/schema-definition'
|
|
6
|
+
import { Schema } from '@contember/schema'
|
|
7
|
+
import { emptySchema } from '@contember/schema-utils'
|
|
8
|
+
import {
|
|
9
|
+
JsonLoader,
|
|
10
|
+
MigrationCreator,
|
|
11
|
+
MigrationFilesManager,
|
|
12
|
+
MigrationParser,
|
|
13
|
+
MigrationsResolver,
|
|
14
|
+
ModificationHandlerFactory,
|
|
15
|
+
SchemaDiffer,
|
|
16
|
+
SchemaMigrator,
|
|
17
|
+
SchemaStateManager,
|
|
18
|
+
SchemaVersionBuilder,
|
|
19
|
+
VERSION_LATEST,
|
|
20
|
+
} from '@contember/migrations-client'
|
|
21
|
+
import { Input } from '@contember/cli-common'
|
|
22
|
+
import { MigrationAmendCommand } from '../../../src/commands/migrations/MigrationAmendCommand.js'
|
|
23
|
+
import { SchemaLoader } from '../../../src/lib/schema/SchemaLoader.js'
|
|
24
|
+
|
|
25
|
+
namespace BlogModel {
|
|
26
|
+
export class Author {
|
|
27
|
+
name = c.stringColumn()
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
namespace BlogModelExtended {
|
|
32
|
+
export class Author {
|
|
33
|
+
name = c.stringColumn()
|
|
34
|
+
nickname = c.stringColumn()
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const aclWith = (role: string): Schema['acl'] => ({
|
|
39
|
+
roles: {
|
|
40
|
+
[role]: { variables: {}, stages: '*', entities: {} },
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
type SystemClientCall = { method: 'migrate' | 'migrationDelete' | 'migrationModify'; args: any[] }
|
|
45
|
+
|
|
46
|
+
// A system client that records calls instead of hitting the network. `get()` throws by default so a
|
|
47
|
+
// state-only amend (which must not touch the server) fails loudly if it ever reaches out.
|
|
48
|
+
const recordingSystemClient = (calls?: SystemClientCall[]) => ({
|
|
49
|
+
get: () => {
|
|
50
|
+
if (!calls) {
|
|
51
|
+
throw new Error('systemClient must not be used for a state-only amend')
|
|
52
|
+
}
|
|
53
|
+
const record = (method: SystemClientCall['method']) => async (...args: any[]) => {
|
|
54
|
+
calls.push({ method, args })
|
|
55
|
+
}
|
|
56
|
+
return { migrate: record('migrate'), migrationDelete: record('migrationDelete'), migrationModify: record('migrationModify') }
|
|
57
|
+
},
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// Builds an amend command wired with real migrations-client services backed by `migrationsDir`.
|
|
61
|
+
const buildCommand = (migrationsDir: string, loadedSchema: Schema, calls?: SystemClientCall[]) => {
|
|
62
|
+
const filesManager = new MigrationFilesManager(migrationsDir, { json: new JsonLoader(new MigrationParser()) })
|
|
63
|
+
const migrationsResolver = new MigrationsResolver(filesManager)
|
|
64
|
+
const schemaMigrator = new SchemaMigrator(new ModificationHandlerFactory(ModificationHandlerFactory.defaultFactoryMap))
|
|
65
|
+
const schemaStateManager = new SchemaStateManager(path.join(migrationsDir, 'state'))
|
|
66
|
+
const schemaVersionBuilder = new SchemaVersionBuilder(migrationsResolver, schemaMigrator, schemaStateManager)
|
|
67
|
+
const migrationCreator = new MigrationCreator(filesManager, new SchemaDiffer(schemaMigrator))
|
|
68
|
+
|
|
69
|
+
const schemaLoader: SchemaLoader = { loadSchema: async () => loadedSchema }
|
|
70
|
+
const statusFacade = { resolveMigrationsStatus: async () => ({ migrationsToExecute: [] }) }
|
|
71
|
+
const migrationsValidator = { validate: async () => true }
|
|
72
|
+
const migrationPrinter = { printMigrationDescription: () => {} }
|
|
73
|
+
|
|
74
|
+
const command = new MigrationAmendCommand(
|
|
75
|
+
migrationsResolver,
|
|
76
|
+
recordingSystemClient(calls) as any,
|
|
77
|
+
statusFacade as any,
|
|
78
|
+
schemaLoader,
|
|
79
|
+
schemaVersionBuilder,
|
|
80
|
+
migrationCreator,
|
|
81
|
+
migrationsValidator as any,
|
|
82
|
+
migrationPrinter as any,
|
|
83
|
+
schemaMigrator,
|
|
84
|
+
schemaStateManager,
|
|
85
|
+
)
|
|
86
|
+
return { command, schemaStateManager }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const run = (command: MigrationAmendCommand) => command.execute(new Input({}, { force: false, yes: true }))
|
|
90
|
+
|
|
91
|
+
describe('MigrationAmendCommand (schema state mode)', () => {
|
|
92
|
+
let migrationsDir: string
|
|
93
|
+
|
|
94
|
+
beforeEach(async () => {
|
|
95
|
+
migrationsDir = await fs.mkdtemp(path.join(os.tmpdir(), 'contember-amend-'))
|
|
96
|
+
|
|
97
|
+
const schemaDiffer = new SchemaDiffer(new SchemaMigrator(new ModificationHandlerFactory(ModificationHandlerFactory.defaultFactoryMap)))
|
|
98
|
+
const model = createSchema(BlogModel)
|
|
99
|
+
// model-only migration, exactly as state mode would produce (non-model parts live in state/ files)
|
|
100
|
+
const modifications = schemaDiffer.diffSchemas(emptySchema, model, { skipNonModelDiffers: true })
|
|
101
|
+
await fs.writeFile(
|
|
102
|
+
path.join(migrationsDir, '2024-01-01-120000-init.json'),
|
|
103
|
+
JSON.stringify({ formatVersion: VERSION_LATEST, modifications }, null, '\t'),
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
// enable state mode with an initial ACL granting the `admin` role
|
|
107
|
+
const stateManager = new SchemaStateManager(path.join(migrationsDir, 'state'))
|
|
108
|
+
await stateManager.extractState({ ...model, acl: aclWith('admin') })
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
afterEach(async () => {
|
|
112
|
+
await fs.rm(migrationsDir, { recursive: true, force: true })
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
test('rewrites state files when only non-model parts changed', async () => {
|
|
116
|
+
const model = createSchema(BlogModel)
|
|
117
|
+
// same model, different ACL — the diff is non-model only, so no migration is produced
|
|
118
|
+
const { command, schemaStateManager } = buildCommand(migrationsDir, { ...model, acl: aclWith('editor') })
|
|
119
|
+
|
|
120
|
+
const code = await run(command)
|
|
121
|
+
|
|
122
|
+
expect(code).toBe(0)
|
|
123
|
+
const state = await schemaStateManager.readState()
|
|
124
|
+
expect(Object.keys(state.acl.roles)).toStrictEqual(['editor'])
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
test('leaves state untouched when nothing changed', async () => {
|
|
128
|
+
const model = createSchema(BlogModel)
|
|
129
|
+
// identical model and ACL — nothing to do, state files must not be rewritten
|
|
130
|
+
const { command, schemaStateManager } = buildCommand(migrationsDir, { ...model, acl: aclWith('admin') })
|
|
131
|
+
|
|
132
|
+
const code = await run(command)
|
|
133
|
+
|
|
134
|
+
expect(code).toBe(0)
|
|
135
|
+
const state = await schemaStateManager.readState()
|
|
136
|
+
expect(Object.keys(state.acl.roles)).toStrictEqual(['admin'])
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
test('re-pushes schema state to the server after amending model changes', async () => {
|
|
140
|
+
// model changed (a column added) — migrationModify rebuilds the server schema from migrations
|
|
141
|
+
// and drops the non-model state, so amend must re-apply the state via a follow-up migrate call.
|
|
142
|
+
const loaded: Schema = { ...createSchema(BlogModelExtended), acl: aclWith('admin') }
|
|
143
|
+
const calls: SystemClientCall[] = []
|
|
144
|
+
const { command } = buildCommand(migrationsDir, loaded, calls)
|
|
145
|
+
|
|
146
|
+
const code = await run(command)
|
|
147
|
+
|
|
148
|
+
expect(code).toBe(0)
|
|
149
|
+
const modifyIndex = calls.findIndex(it => it.method === 'migrationModify')
|
|
150
|
+
expect(modifyIndex).toBeGreaterThanOrEqual(0)
|
|
151
|
+
// the state re-push is a migrate call carrying schemaState, after the migrationModify
|
|
152
|
+
const restate = calls.slice(modifyIndex + 1).find(it => it.method === 'migrate' && it.args[2])
|
|
153
|
+
expect(restate).toBeDefined()
|
|
154
|
+
expect(Object.keys(restate!.args[2].acl.roles)).toStrictEqual(['admin'])
|
|
155
|
+
})
|
|
156
|
+
})
|