From ef2cfc20edb3016d6ab99aa1fc3f0e389f5e227d Mon Sep 17 00:00:00 2001 From: serverpod_docs Date: Tue, 5 Nov 2024 13:24:41 +0000 Subject: [PATCH] Deployed by Serverpod docs deploy action --- docs/0.9.10.html | 2 +- docs/0.9.10/capabilities.html | 2 +- docs/0.9.10/concepts/authentication.html | 2 +- docs/0.9.10/concepts/caching.html | 2 +- docs/0.9.10/concepts/database-communication.html | 2 +- docs/0.9.10/concepts/file-uploads.html | 2 +- docs/0.9.10/concepts/logging.html | 2 +- docs/0.9.10/concepts/modules.html | 2 +- docs/0.9.10/concepts/serialization.html | 2 +- docs/0.9.10/concepts/streams.html | 2 +- docs/0.9.10/concepts/webserver.html | 2 +- docs/0.9.10/concepts/working-with-endpoints.html | 2 +- docs/0.9.10/contribute.html | 2 +- docs/0.9.10/deployments/deploying-to-aws.html | 2 +- docs/0.9.10/deployments/general.html | 2 +- docs/0.9.10/roadmap.html | 2 +- docs/0.9.10/support.html | 2 +- docs/0.9.11.html | 2 +- docs/0.9.11/capabilities.html | 2 +- docs/0.9.11/concepts/authentication.html | 2 +- docs/0.9.11/concepts/caching.html | 2 +- docs/0.9.11/concepts/database-communication.html | 2 +- docs/0.9.11/concepts/file-uploads.html | 2 +- docs/0.9.11/concepts/logging.html | 2 +- docs/0.9.11/concepts/modules.html | 2 +- docs/0.9.11/concepts/serialization.html | 2 +- docs/0.9.11/concepts/streams.html | 2 +- docs/0.9.11/concepts/webserver.html | 2 +- docs/0.9.11/concepts/working-with-endpoints.html | 2 +- docs/0.9.11/contribute.html | 2 +- docs/0.9.11/deployments/deploying-to-aws.html | 2 +- docs/0.9.11/deployments/general.html | 2 +- docs/0.9.11/roadmap.html | 2 +- docs/0.9.11/support.html | 2 +- docs/0.9.20.html | 2 +- docs/0.9.20/capabilities.html | 2 +- docs/0.9.20/concepts/authentication.html | 2 +- docs/0.9.20/concepts/backward-compatibility.html | 2 +- docs/0.9.20/concepts/caching.html | 2 +- docs/0.9.20/concepts/database-communication.html | 2 +- docs/0.9.20/concepts/file-uploads.html | 2 +- docs/0.9.20/concepts/health-checks.html | 2 +- docs/0.9.20/concepts/logging.html | 2 +- docs/0.9.20/concepts/modules.html | 2 +- docs/0.9.20/concepts/serialization.html | 2 +- docs/0.9.20/concepts/streams.html | 2 +- docs/0.9.20/concepts/webserver.html | 2 +- docs/0.9.20/concepts/working-with-endpoints.html | 2 +- docs/0.9.20/contribute.html | 2 +- docs/0.9.20/deployments/deploying-to-aws.html | 2 +- docs/0.9.20/deployments/general.html | 2 +- docs/0.9.20/roadmap.html | 2 +- docs/0.9.20/support.html | 2 +- docs/0.9.20/tutorials.html | 2 +- docs/0.9.21.html | 2 +- docs/0.9.21/capabilities.html | 2 +- docs/0.9.21/concepts/authentication.html | 2 +- docs/0.9.21/concepts/backward-compatibility.html | 2 +- docs/0.9.21/concepts/caching.html | 2 +- docs/0.9.21/concepts/database-communication.html | 2 +- docs/0.9.21/concepts/file-uploads.html | 2 +- docs/0.9.21/concepts/health-checks.html | 2 +- docs/0.9.21/concepts/logging.html | 2 +- docs/0.9.21/concepts/modules.html | 2 +- docs/0.9.21/concepts/serialization.html | 2 +- docs/0.9.21/concepts/streams.html | 2 +- docs/0.9.21/concepts/webserver.html | 2 +- docs/0.9.21/concepts/working-with-endpoints.html | 2 +- docs/0.9.21/contribute.html | 2 +- docs/0.9.21/deployments/deploying-to-aws.html | 2 +- docs/0.9.21/deployments/general.html | 2 +- docs/0.9.21/roadmap.html | 2 +- docs/0.9.21/support.html | 2 +- docs/0.9.21/tutorials.html | 2 +- docs/0.9.22.html | 2 +- docs/0.9.22/capabilities.html | 2 +- docs/0.9.22/concepts/authentication.html | 2 +- docs/0.9.22/concepts/backward-compatibility.html | 2 +- docs/0.9.22/concepts/caching.html | 2 +- docs/0.9.22/concepts/database-communication.html | 2 +- docs/0.9.22/concepts/file-uploads.html | 2 +- docs/0.9.22/concepts/health-checks.html | 2 +- docs/0.9.22/concepts/logging.html | 2 +- docs/0.9.22/concepts/modules.html | 2 +- docs/0.9.22/concepts/serialization.html | 2 +- docs/0.9.22/concepts/streams.html | 2 +- docs/0.9.22/concepts/webserver.html | 2 +- docs/0.9.22/concepts/working-with-endpoints.html | 2 +- docs/0.9.22/contribute.html | 2 +- docs/0.9.22/deployments/deploying-to-aws.html | 2 +- docs/0.9.22/deployments/general.html | 2 +- docs/0.9.22/roadmap.html | 2 +- docs/0.9.22/support.html | 2 +- docs/0.9.22/tutorials.html | 2 +- docs/0.9.5.html | 2 +- docs/0.9.5/capabilities.html | 2 +- docs/0.9.5/concepts/authentication.html | 2 +- docs/0.9.5/concepts/caching.html | 2 +- docs/0.9.5/concepts/database-communication.html | 2 +- docs/0.9.5/concepts/file-uploads.html | 2 +- docs/0.9.5/concepts/logging.html | 2 +- docs/0.9.5/concepts/modules.html | 2 +- docs/0.9.5/concepts/serialization.html | 2 +- docs/0.9.5/concepts/streams.html | 2 +- docs/0.9.5/concepts/working-with-endpoints.html | 2 +- docs/0.9.5/contribute.html | 2 +- docs/0.9.5/deployments/general.html | 2 +- docs/0.9.5/roadmap.html | 2 +- docs/0.9.6.html | 2 +- docs/0.9.6/capabilities.html | 2 +- docs/0.9.6/concepts/authentication.html | 2 +- docs/0.9.6/concepts/caching.html | 2 +- docs/0.9.6/concepts/database-communication.html | 2 +- docs/0.9.6/concepts/file-uploads.html | 2 +- docs/0.9.6/concepts/logging.html | 2 +- docs/0.9.6/concepts/modules.html | 2 +- docs/0.9.6/concepts/serialization.html | 2 +- docs/0.9.6/concepts/streams.html | 2 +- docs/0.9.6/concepts/working-with-endpoints.html | 2 +- docs/0.9.6/contribute.html | 2 +- docs/0.9.6/deployments/general.html | 2 +- docs/0.9.6/roadmap.html | 2 +- docs/0.9.7.html | 2 +- docs/0.9.7/capabilities.html | 2 +- docs/0.9.7/concepts/authentication.html | 2 +- docs/0.9.7/concepts/caching.html | 2 +- docs/0.9.7/concepts/database-communication.html | 2 +- docs/0.9.7/concepts/file-uploads.html | 2 +- docs/0.9.7/concepts/logging.html | 2 +- docs/0.9.7/concepts/modules.html | 2 +- docs/0.9.7/concepts/serialization.html | 2 +- docs/0.9.7/concepts/streams.html | 2 +- docs/0.9.7/concepts/working-with-endpoints.html | 2 +- docs/0.9.7/contribute.html | 2 +- docs/0.9.7/deployments/general.html | 2 +- docs/0.9.7/roadmap.html | 2 +- docs/0.9.7/support.html | 2 +- docs/0.9.8.html | 2 +- docs/0.9.8/capabilities.html | 2 +- docs/0.9.8/concepts/authentication.html | 2 +- docs/0.9.8/concepts/caching.html | 2 +- docs/0.9.8/concepts/database-communication.html | 2 +- docs/0.9.8/concepts/file-uploads.html | 2 +- docs/0.9.8/concepts/logging.html | 2 +- docs/0.9.8/concepts/modules.html | 2 +- docs/0.9.8/concepts/serialization.html | 2 +- docs/0.9.8/concepts/streams.html | 2 +- docs/0.9.8/concepts/working-with-endpoints.html | 2 +- docs/0.9.8/contribute.html | 2 +- docs/0.9.8/deployments/deploying-to-aws.html | 2 +- docs/0.9.8/deployments/general.html | 2 +- docs/0.9.8/roadmap.html | 2 +- docs/0.9.8/support.html | 2 +- docs/0.9.9.html | 2 +- docs/0.9.9/capabilities.html | 2 +- docs/0.9.9/concepts/authentication.html | 2 +- docs/0.9.9/concepts/caching.html | 2 +- docs/0.9.9/concepts/database-communication.html | 2 +- docs/0.9.9/concepts/file-uploads.html | 2 +- docs/0.9.9/concepts/logging.html | 2 +- docs/0.9.9/concepts/modules.html | 2 +- docs/0.9.9/concepts/serialization.html | 2 +- docs/0.9.9/concepts/streams.html | 2 +- docs/0.9.9/concepts/webserver.html | 2 +- docs/0.9.9/concepts/working-with-endpoints.html | 2 +- docs/0.9.9/contribute.html | 2 +- docs/0.9.9/deployments/deploying-to-aws.html | 2 +- docs/0.9.9/deployments/general.html | 2 +- docs/0.9.9/roadmap.html | 2 +- docs/0.9.9/support.html | 2 +- docs/1.0.0.html | 2 +- docs/1.0.0/capabilities.html | 2 +- docs/1.0.0/concepts/authentication.html | 2 +- docs/1.0.0/concepts/backward-compatibility.html | 2 +- docs/1.0.0/concepts/caching.html | 2 +- docs/1.0.0/concepts/database-communication.html | 2 +- docs/1.0.0/concepts/file-uploads.html | 2 +- docs/1.0.0/concepts/health-checks.html | 2 +- docs/1.0.0/concepts/logging.html | 2 +- docs/1.0.0/concepts/modules.html | 2 +- docs/1.0.0/concepts/serialization.html | 2 +- docs/1.0.0/concepts/streams.html | 2 +- docs/1.0.0/concepts/webserver.html | 2 +- docs/1.0.0/concepts/working-with-endpoints.html | 2 +- docs/1.0.0/contribute.html | 2 +- docs/1.0.0/deployments/deploying-to-aws.html | 2 +- docs/1.0.0/deployments/general.html | 2 +- docs/1.0.0/roadmap.html | 2 +- docs/1.0.0/support.html | 2 +- docs/1.0.0/tutorials.html | 2 +- docs/1.1.0.html | 2 +- docs/1.1.0/capabilities.html | 2 +- docs/1.1.0/concepts/authentication.html | 2 +- docs/1.1.0/concepts/backward-compatibility.html | 2 +- docs/1.1.0/concepts/caching.html | 2 +- docs/1.1.0/concepts/database-communication.html | 2 +- docs/1.1.0/concepts/exceptions.html | 2 +- docs/1.1.0/concepts/file-uploads.html | 2 +- docs/1.1.0/concepts/health-checks.html | 2 +- docs/1.1.0/concepts/logging.html | 2 +- docs/1.1.0/concepts/modules.html | 2 +- docs/1.1.0/concepts/serialization.html | 2 +- docs/1.1.0/concepts/sessions.html | 2 +- docs/1.1.0/concepts/streams.html | 2 +- docs/1.1.0/concepts/webserver.html | 2 +- docs/1.1.0/concepts/working-with-endpoints.html | 2 +- docs/1.1.0/contribute.html | 2 +- docs/1.1.0/deployments/deploying-to-aws.html | 2 +- docs/1.1.0/deployments/deploying-to-gce-terraform.html | 2 +- docs/1.1.0/deployments/deploying-to-gcr-console.html | 2 +- docs/1.1.0/deployments/deployment-strategy.html | 2 +- docs/1.1.0/deployments/general.html | 2 +- docs/1.1.0/insights.html | 2 +- docs/1.1.0/roadmap.html | 2 +- docs/1.1.0/support.html | 2 +- docs/1.1.0/tutorials.html | 2 +- docs/1.1.1.html | 2 +- docs/1.1.1/capabilities.html | 2 +- docs/1.1.1/concepts/authentication/basics.html | 2 +- docs/1.1.1/concepts/authentication/providers/apple.html | 2 +- docs/1.1.1/concepts/authentication/providers/email.html | 2 +- docs/1.1.1/concepts/authentication/providers/firebase.html | 2 +- docs/1.1.1/concepts/authentication/providers/google.html | 2 +- docs/1.1.1/concepts/authentication/setup.html | 2 +- docs/1.1.1/concepts/authentication/working-with-users.html | 2 +- docs/1.1.1/concepts/backward-compatibility.html | 2 +- docs/1.1.1/concepts/caching.html | 2 +- docs/1.1.1/concepts/database-communication.html | 2 +- docs/1.1.1/concepts/exceptions.html | 2 +- docs/1.1.1/concepts/file-uploads.html | 2 +- docs/1.1.1/concepts/health-checks.html | 2 +- docs/1.1.1/concepts/logging.html | 2 +- docs/1.1.1/concepts/modules.html | 2 +- docs/1.1.1/concepts/serialization.html | 2 +- docs/1.1.1/concepts/sessions.html | 2 +- docs/1.1.1/concepts/streams.html | 2 +- docs/1.1.1/concepts/webserver.html | 2 +- docs/1.1.1/concepts/working-with-endpoints.html | 2 +- docs/1.1.1/contribute.html | 2 +- docs/1.1.1/deployments/deploying-to-aws.html | 2 +- docs/1.1.1/deployments/deploying-to-gce-terraform.html | 2 +- docs/1.1.1/deployments/deploying-to-gcr-console.html | 2 +- docs/1.1.1/deployments/deployment-strategy.html | 2 +- docs/1.1.1/deployments/general.html | 2 +- docs/1.1.1/get-started.html | 2 +- docs/1.1.1/insights.html | 2 +- docs/1.1.1/roadmap.html | 2 +- docs/1.1.1/support.html | 2 +- docs/1.1.1/tutorials/authentication.html | 2 +- docs/1.1.1/tutorials/code-example.html | 2 +- docs/1.1.1/tutorials/first-app.html | 2 +- docs/1.1.1/tutorials/videos.html | 2 +- docs/1.2.0.html | 2 +- docs/1.2.0/capabilities.html | 2 +- docs/1.2.0/cli.html | 2 +- docs/1.2.0/concepts/authentication/basics.html | 2 +- docs/1.2.0/concepts/authentication/custom-overrides.html | 2 +- docs/1.2.0/concepts/authentication/providers/apple.html | 2 +- .../concepts/authentication/providers/custom-providers.html | 2 +- docs/1.2.0/concepts/authentication/providers/email.html | 2 +- docs/1.2.0/concepts/authentication/providers/firebase.html | 2 +- docs/1.2.0/concepts/authentication/providers/google.html | 2 +- docs/1.2.0/concepts/authentication/setup.html | 2 +- docs/1.2.0/concepts/authentication/working-with-users.html | 2 +- docs/1.2.0/concepts/backward-compatibility.html | 2 +- docs/1.2.0/concepts/caching.html | 2 +- docs/1.2.0/concepts/database/connection.html | 2 +- docs/1.2.0/concepts/database/crud.html | 2 +- docs/1.2.0/concepts/database/filter.html | 2 +- docs/1.2.0/concepts/database/indexing.html | 2 +- docs/1.2.0/concepts/database/migrations.html | 2 +- docs/1.2.0/concepts/database/models.html | 2 +- docs/1.2.0/concepts/database/pagination.html | 2 +- docs/1.2.0/concepts/database/raw-access.html | 2 +- docs/1.2.0/concepts/database/relation-queries.html | 2 +- docs/1.2.0/concepts/database/relations/many-to-many.html | 2 +- docs/1.2.0/concepts/database/relations/modules.html | 2 +- docs/1.2.0/concepts/database/relations/one-to-many.html | 2 +- docs/1.2.0/concepts/database/relations/one-to-one.html | 2 +- .../concepts/database/relations/referential-actions.html | 2 +- docs/1.2.0/concepts/database/relations/self-relations.html | 2 +- docs/1.2.0/concepts/database/sort.html | 2 +- docs/1.2.0/concepts/database/transactions.html | 2 +- docs/1.2.0/concepts/exceptions.html | 2 +- docs/1.2.0/concepts/file-uploads.html | 2 +- docs/1.2.0/concepts/health-checks.html | 2 +- docs/1.2.0/concepts/logging.html | 2 +- docs/1.2.0/concepts/models.html | 4 ++-- docs/1.2.0/concepts/modules.html | 2 +- docs/1.2.0/concepts/scheduling.html | 2 +- docs/1.2.0/concepts/serialization.html | 2 +- docs/1.2.0/concepts/sessions.html | 2 +- docs/1.2.0/concepts/streams.html | 2 +- docs/1.2.0/concepts/webserver.html | 2 +- docs/1.2.0/concepts/working-with-endpoints.html | 2 +- docs/1.2.0/contribute.html | 2 +- docs/1.2.0/deployments/deploying-to-aws.html | 2 +- docs/1.2.0/deployments/deploying-to-gce-terraform.html | 2 +- docs/1.2.0/deployments/deploying-to-gcr-console.html | 2 +- docs/1.2.0/deployments/deployment-strategy.html | 2 +- docs/1.2.0/deployments/general.html | 2 +- docs/1.2.0/get-started.html | 2 +- docs/1.2.0/insights.html | 2 +- docs/1.2.0/lsp.html | 2 +- docs/1.2.0/roadmap.html | 2 +- docs/1.2.0/support.html | 2 +- docs/1.2.0/tutorials/authentication.html | 2 +- docs/1.2.0/tutorials/code-example.html | 2 +- docs/1.2.0/tutorials/first-app.html | 2 +- docs/1.2.0/tutorials/videos.html | 2 +- docs/1.2.0/upgrading/upgrade-to-one-point-two.html | 2 +- docs/2.0.0.html | 2 +- docs/2.0.0/capabilities.html | 2 +- docs/2.0.0/concepts/authentication/basics.html | 2 +- docs/2.0.0/concepts/authentication/custom-overrides.html | 2 +- docs/2.0.0/concepts/authentication/providers/apple.html | 2 +- .../concepts/authentication/providers/custom-providers.html | 2 +- docs/2.0.0/concepts/authentication/providers/email.html | 2 +- docs/2.0.0/concepts/authentication/providers/firebase.html | 2 +- docs/2.0.0/concepts/authentication/providers/google.html | 2 +- docs/2.0.0/concepts/authentication/setup.html | 2 +- docs/2.0.0/concepts/authentication/working-with-users.html | 2 +- docs/2.0.0/concepts/backward-compatibility.html | 2 +- docs/2.0.0/concepts/caching.html | 2 +- docs/2.0.0/concepts/database/connection.html | 2 +- docs/2.0.0/concepts/database/crud.html | 2 +- docs/2.0.0/concepts/database/filter.html | 2 +- docs/2.0.0/concepts/database/indexing.html | 2 +- docs/2.0.0/concepts/database/migrations.html | 2 +- docs/2.0.0/concepts/database/models.html | 2 +- docs/2.0.0/concepts/database/pagination.html | 2 +- docs/2.0.0/concepts/database/raw-access.html | 2 +- docs/2.0.0/concepts/database/relation-queries.html | 2 +- docs/2.0.0/concepts/database/relations/many-to-many.html | 2 +- docs/2.0.0/concepts/database/relations/modules.html | 2 +- docs/2.0.0/concepts/database/relations/one-to-many.html | 2 +- docs/2.0.0/concepts/database/relations/one-to-one.html | 2 +- .../concepts/database/relations/referential-actions.html | 2 +- docs/2.0.0/concepts/database/relations/self-relations.html | 2 +- docs/2.0.0/concepts/database/sort.html | 2 +- docs/2.0.0/concepts/database/transactions.html | 2 +- docs/2.0.0/concepts/exceptions.html | 2 +- docs/2.0.0/concepts/file-uploads.html | 2 +- docs/2.0.0/concepts/health-checks.html | 2 +- docs/2.0.0/concepts/logging.html | 2 +- docs/2.0.0/concepts/models.html | 4 ++-- docs/2.0.0/concepts/modules.html | 2 +- docs/2.0.0/concepts/scheduling.html | 2 +- docs/2.0.0/concepts/serialization.html | 2 +- docs/2.0.0/concepts/sessions.html | 2 +- docs/2.0.0/concepts/streams.html | 2 +- docs/2.0.0/concepts/webserver.html | 2 +- docs/2.0.0/concepts/working-with-endpoints.html | 2 +- docs/2.0.0/contribute.html | 2 +- docs/2.0.0/deployments/deploying-to-aws.html | 2 +- docs/2.0.0/deployments/deploying-to-gce-terraform.html | 2 +- docs/2.0.0/deployments/deploying-to-gcr-console.html | 2 +- docs/2.0.0/deployments/deployment-strategy.html | 2 +- docs/2.0.0/deployments/general.html | 2 +- docs/2.0.0/get-started.html | 2 +- docs/2.0.0/roadmap.html | 2 +- docs/2.0.0/support.html | 2 +- docs/2.0.0/tools/cli.html | 2 +- docs/2.0.0/tools/insights.html | 2 +- docs/2.0.0/tools/lsp.html | 2 +- docs/2.0.0/tutorials/authentication.html | 2 +- docs/2.0.0/tutorials/code-example.html | 2 +- docs/2.0.0/tutorials/first-app.html | 2 +- docs/2.0.0/tutorials/videos.html | 2 +- docs/2.0.0/upgrading/upgrade-to-one-point-two.html | 2 +- docs/2.0.0/upgrading/upgrade-to-two.html | 4 ++-- docs/404.html | 2 +- docs/assets/js/{1b218eaa.7f79a47a.js => 1b218eaa.4a46f698.js} | 2 +- docs/assets/js/{32b8fafb.d51c7aa0.js => 32b8fafb.439ef5f1.js} | 2 +- docs/assets/js/{441fd5fc.c6c289b1.js => 441fd5fc.fa9f8a31.js} | 2 +- docs/assets/js/{7ac69e68.07813519.js => 7ac69e68.e3dc9e21.js} | 2 +- docs/assets/js/{8615e055.46cbd86e.js => 8615e055.a738aae6.js} | 2 +- docs/assets/js/{ac5db01d.433c50c6.js => ac5db01d.bf926c46.js} | 2 +- docs/assets/js/{cce58fe7.dbb843db.js => cce58fe7.dd0a4d50.js} | 2 +- .../js/{runtime~main.e1bfa786.js => runtime~main.238171b8.js} | 2 +- docs/capabilities.html | 2 +- docs/concepts/authentication/basics.html | 2 +- docs/concepts/authentication/custom-overrides.html | 2 +- docs/concepts/authentication/providers/apple.html | 2 +- docs/concepts/authentication/providers/custom-providers.html | 2 +- docs/concepts/authentication/providers/email.html | 2 +- docs/concepts/authentication/providers/firebase.html | 2 +- docs/concepts/authentication/providers/google.html | 2 +- docs/concepts/authentication/setup.html | 2 +- docs/concepts/authentication/working-with-users.html | 2 +- docs/concepts/backward-compatibility.html | 2 +- docs/concepts/caching.html | 2 +- docs/concepts/configuration.html | 2 +- docs/concepts/database/connection.html | 2 +- docs/concepts/database/crud.html | 2 +- docs/concepts/database/filter.html | 2 +- docs/concepts/database/indexing.html | 2 +- docs/concepts/database/migrations.html | 2 +- docs/concepts/database/models.html | 2 +- docs/concepts/database/pagination.html | 2 +- docs/concepts/database/raw-access.html | 2 +- docs/concepts/database/relation-queries.html | 2 +- docs/concepts/database/relations/many-to-many.html | 2 +- docs/concepts/database/relations/modules.html | 2 +- docs/concepts/database/relations/one-to-many.html | 2 +- docs/concepts/database/relations/one-to-one.html | 2 +- docs/concepts/database/relations/referential-actions.html | 2 +- docs/concepts/database/relations/self-relations.html | 2 +- docs/concepts/database/sort.html | 2 +- docs/concepts/database/transactions.html | 2 +- docs/concepts/exceptions.html | 2 +- docs/concepts/file-uploads.html | 2 +- docs/concepts/health-checks.html | 2 +- docs/concepts/logging.html | 2 +- docs/concepts/models.html | 4 ++-- docs/concepts/modules.html | 2 +- docs/concepts/scheduling.html | 2 +- docs/concepts/serialization.html | 2 +- docs/concepts/sessions.html | 2 +- docs/concepts/streams.html | 2 +- docs/concepts/webserver.html | 2 +- docs/concepts/working-with-endpoints.html | 2 +- docs/contribute.html | 2 +- docs/deployments/deploying-to-aws.html | 2 +- docs/deployments/deploying-to-gce-terraform.html | 2 +- docs/deployments/deploying-to-gcr-console.html | 2 +- docs/deployments/deployment-strategy.html | 2 +- docs/deployments/general.html | 2 +- docs/get-started-with-mini.html | 2 +- docs/get-started.html | 2 +- docs/index.html | 2 +- docs/next.html | 2 +- docs/next/capabilities.html | 2 +- docs/next/concepts/authentication/basics.html | 2 +- docs/next/concepts/authentication/custom-overrides.html | 2 +- docs/next/concepts/authentication/providers/apple.html | 2 +- .../concepts/authentication/providers/custom-providers.html | 2 +- docs/next/concepts/authentication/providers/email.html | 2 +- docs/next/concepts/authentication/providers/firebase.html | 2 +- docs/next/concepts/authentication/providers/google.html | 2 +- docs/next/concepts/authentication/setup.html | 2 +- docs/next/concepts/authentication/working-with-users.html | 2 +- docs/next/concepts/backward-compatibility.html | 2 +- docs/next/concepts/caching.html | 2 +- docs/next/concepts/configuration.html | 2 +- docs/next/concepts/database/connection.html | 2 +- docs/next/concepts/database/crud.html | 2 +- docs/next/concepts/database/filter.html | 2 +- docs/next/concepts/database/indexing.html | 2 +- docs/next/concepts/database/migrations.html | 2 +- docs/next/concepts/database/models.html | 2 +- docs/next/concepts/database/pagination.html | 2 +- docs/next/concepts/database/raw-access.html | 2 +- docs/next/concepts/database/relation-queries.html | 2 +- docs/next/concepts/database/relations/many-to-many.html | 2 +- docs/next/concepts/database/relations/modules.html | 2 +- docs/next/concepts/database/relations/one-to-many.html | 2 +- docs/next/concepts/database/relations/one-to-one.html | 2 +- .../next/concepts/database/relations/referential-actions.html | 2 +- docs/next/concepts/database/relations/self-relations.html | 2 +- docs/next/concepts/database/sort.html | 2 +- docs/next/concepts/database/transactions.html | 2 +- docs/next/concepts/exceptions.html | 2 +- docs/next/concepts/experimental.html | 2 +- docs/next/concepts/file-uploads.html | 2 +- docs/next/concepts/health-checks.html | 2 +- docs/next/concepts/logging.html | 2 +- docs/next/concepts/models.html | 4 ++-- docs/next/concepts/modules.html | 2 +- docs/next/concepts/scheduling.html | 2 +- docs/next/concepts/serialization.html | 2 +- docs/next/concepts/sessions.html | 2 +- docs/next/concepts/streams.html | 2 +- docs/next/concepts/testing/advanced-examples.html | 2 +- docs/next/concepts/testing/best-practises.html | 2 +- docs/next/concepts/testing/get-started.html | 2 +- docs/next/concepts/testing/the-basics.html | 2 +- docs/next/concepts/webserver.html | 2 +- docs/next/concepts/working-with-endpoints.html | 2 +- docs/next/contribute.html | 2 +- docs/next/deployments/deploying-to-aws.html | 2 +- docs/next/deployments/deploying-to-gce-terraform.html | 2 +- docs/next/deployments/deploying-to-gcr-console.html | 2 +- docs/next/deployments/deployment-strategy.html | 2 +- docs/next/deployments/general.html | 2 +- docs/next/get-started-with-mini.html | 2 +- docs/next/get-started.html | 2 +- docs/next/support.html | 2 +- docs/next/tools/insights.html | 2 +- docs/next/tools/lsp.html | 2 +- docs/next/tutorials/authentication.html | 2 +- docs/next/tutorials/code-example.html | 2 +- docs/next/tutorials/first-app.html | 2 +- docs/next/tutorials/real-time-communication.html | 2 +- docs/next/upgrading/upgrade-from-mini.html | 2 +- docs/next/upgrading/upgrade-to-one-point-two.html | 2 +- docs/next/upgrading/upgrade-to-two.html | 4 ++-- docs/support.html | 2 +- docs/tools/insights.html | 2 +- docs/tools/lsp.html | 2 +- docs/tutorials/authentication.html | 2 +- docs/tutorials/code-example.html | 2 +- docs/tutorials/first-app.html | 2 +- docs/tutorials/real-time-communication.html | 2 +- docs/upgrading/upgrade-from-mini.html | 2 +- docs/upgrading/upgrade-to-one-point-two.html | 2 +- docs/upgrading/upgrade-to-two.html | 4 ++-- 507 files changed, 514 insertions(+), 514 deletions(-) rename docs/assets/js/{1b218eaa.7f79a47a.js => 1b218eaa.4a46f698.js} (99%) rename docs/assets/js/{32b8fafb.d51c7aa0.js => 32b8fafb.439ef5f1.js} (99%) rename docs/assets/js/{441fd5fc.c6c289b1.js => 441fd5fc.fa9f8a31.js} (99%) rename docs/assets/js/{7ac69e68.07813519.js => 7ac69e68.e3dc9e21.js} (93%) rename docs/assets/js/{8615e055.46cbd86e.js => 8615e055.a738aae6.js} (93%) rename docs/assets/js/{ac5db01d.433c50c6.js => ac5db01d.bf926c46.js} (93%) rename docs/assets/js/{cce58fe7.dbb843db.js => cce58fe7.dd0a4d50.js} (99%) rename docs/assets/js/{runtime~main.e1bfa786.js => runtime~main.238171b8.js} (98%) diff --git a/docs/0.9.10.html b/docs/0.9.10.html index f1c014878..20bdaf45c 100644 --- a/docs/0.9.10.html +++ b/docs/0.9.10.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/0.9.10/capabilities.html b/docs/0.9.10/capabilities.html index 916b0aca0..2f3f85ff5 100644 --- a/docs/0.9.10/capabilities.html +++ b/docs/0.9.10/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/0.9.10/concepts/authentication.html b/docs/0.9.10/concepts/authentication.html index cb34ca83f..fe27b6704 100644 --- a/docs/0.9.10/concepts/authentication.html +++ b/docs/0.9.10/concepts/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/0.9.10/concepts/caching.html b/docs/0.9.10/concepts/caching.html index 8a5a485ed..a14837bba 100644 --- a/docs/0.9.10/concepts/caching.html +++ b/docs/0.9.10/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/0.9.10/concepts/database-communication.html b/docs/0.9.10/concepts/database-communication.html index b965bcc7b..82e75e590 100644 --- a/docs/0.9.10/concepts/database-communication.html +++ b/docs/0.9.10/concepts/database-communication.html @@ -4,7 +4,7 @@ Database communication | Serverpod - + diff --git a/docs/0.9.10/concepts/file-uploads.html b/docs/0.9.10/concepts/file-uploads.html index 33ce22d6d..7123a111c 100644 --- a/docs/0.9.10/concepts/file-uploads.html +++ b/docs/0.9.10/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/0.9.10/concepts/logging.html b/docs/0.9.10/concepts/logging.html index be2d3cc55..70f9ec223 100644 --- a/docs/0.9.10/concepts/logging.html +++ b/docs/0.9.10/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/0.9.10/concepts/modules.html b/docs/0.9.10/concepts/modules.html index 8510e4c3d..eba2f9c25 100644 --- a/docs/0.9.10/concepts/modules.html +++ b/docs/0.9.10/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/0.9.10/concepts/serialization.html b/docs/0.9.10/concepts/serialization.html index 260af5404..7a1aae051 100644 --- a/docs/0.9.10/concepts/serialization.html +++ b/docs/0.9.10/concepts/serialization.html @@ -4,7 +4,7 @@ Serialization | Serverpod - + diff --git a/docs/0.9.10/concepts/streams.html b/docs/0.9.10/concepts/streams.html index 729fad486..886317e19 100644 --- a/docs/0.9.10/concepts/streams.html +++ b/docs/0.9.10/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/0.9.10/concepts/webserver.html b/docs/0.9.10/concepts/webserver.html index befe01432..176c7ce17 100644 --- a/docs/0.9.10/concepts/webserver.html +++ b/docs/0.9.10/concepts/webserver.html @@ -4,7 +4,7 @@ Web server | Serverpod - + diff --git a/docs/0.9.10/concepts/working-with-endpoints.html b/docs/0.9.10/concepts/working-with-endpoints.html index 2dd2198eb..a23a03800 100644 --- a/docs/0.9.10/concepts/working-with-endpoints.html +++ b/docs/0.9.10/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/0.9.10/contribute.html b/docs/0.9.10/contribute.html index 3270fa5f9..8c21415be 100644 --- a/docs/0.9.10/contribute.html +++ b/docs/0.9.10/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/0.9.10/deployments/deploying-to-aws.html b/docs/0.9.10/deployments/deploying-to-aws.html index d30692703..115f45a88 100644 --- a/docs/0.9.10/deployments/deploying-to-aws.html +++ b/docs/0.9.10/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ Deploying to AWS | Serverpod - + diff --git a/docs/0.9.10/deployments/general.html b/docs/0.9.10/deployments/general.html index b249377c7..92403a0c4 100644 --- a/docs/0.9.10/deployments/general.html +++ b/docs/0.9.10/deployments/general.html @@ -4,7 +4,7 @@ General notes | Serverpod - + diff --git a/docs/0.9.10/roadmap.html b/docs/0.9.10/roadmap.html index 3e57817db..6ca483b29 100644 --- a/docs/0.9.10/roadmap.html +++ b/docs/0.9.10/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/0.9.10/support.html b/docs/0.9.10/support.html index c3c38c920..3d1dd4866 100644 --- a/docs/0.9.10/support.html +++ b/docs/0.9.10/support.html @@ -4,7 +4,7 @@ Support & community | Serverpod - + diff --git a/docs/0.9.11.html b/docs/0.9.11.html index 34ec743de..b20b910c2 100644 --- a/docs/0.9.11.html +++ b/docs/0.9.11.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/0.9.11/capabilities.html b/docs/0.9.11/capabilities.html index b2d53aee5..20c71ca08 100644 --- a/docs/0.9.11/capabilities.html +++ b/docs/0.9.11/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/0.9.11/concepts/authentication.html b/docs/0.9.11/concepts/authentication.html index 4bffe948b..6677add2f 100644 --- a/docs/0.9.11/concepts/authentication.html +++ b/docs/0.9.11/concepts/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/0.9.11/concepts/caching.html b/docs/0.9.11/concepts/caching.html index 3f064b517..5a320fa2f 100644 --- a/docs/0.9.11/concepts/caching.html +++ b/docs/0.9.11/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/0.9.11/concepts/database-communication.html b/docs/0.9.11/concepts/database-communication.html index 8c6b11c44..ba02816dd 100644 --- a/docs/0.9.11/concepts/database-communication.html +++ b/docs/0.9.11/concepts/database-communication.html @@ -4,7 +4,7 @@ Database communication | Serverpod - + diff --git a/docs/0.9.11/concepts/file-uploads.html b/docs/0.9.11/concepts/file-uploads.html index dceaa5b03..599399297 100644 --- a/docs/0.9.11/concepts/file-uploads.html +++ b/docs/0.9.11/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/0.9.11/concepts/logging.html b/docs/0.9.11/concepts/logging.html index 29e0d3a12..aeb77f2f1 100644 --- a/docs/0.9.11/concepts/logging.html +++ b/docs/0.9.11/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/0.9.11/concepts/modules.html b/docs/0.9.11/concepts/modules.html index 97bc51416..ffbf25bd2 100644 --- a/docs/0.9.11/concepts/modules.html +++ b/docs/0.9.11/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/0.9.11/concepts/serialization.html b/docs/0.9.11/concepts/serialization.html index 5708cad9e..19335c86e 100644 --- a/docs/0.9.11/concepts/serialization.html +++ b/docs/0.9.11/concepts/serialization.html @@ -4,7 +4,7 @@ Serialization | Serverpod - + diff --git a/docs/0.9.11/concepts/streams.html b/docs/0.9.11/concepts/streams.html index 96a2ca1bd..3a5aa72d7 100644 --- a/docs/0.9.11/concepts/streams.html +++ b/docs/0.9.11/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/0.9.11/concepts/webserver.html b/docs/0.9.11/concepts/webserver.html index f67ebb83e..e221ddb99 100644 --- a/docs/0.9.11/concepts/webserver.html +++ b/docs/0.9.11/concepts/webserver.html @@ -4,7 +4,7 @@ Web server | Serverpod - + diff --git a/docs/0.9.11/concepts/working-with-endpoints.html b/docs/0.9.11/concepts/working-with-endpoints.html index 9a9a23014..518b425ba 100644 --- a/docs/0.9.11/concepts/working-with-endpoints.html +++ b/docs/0.9.11/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/0.9.11/contribute.html b/docs/0.9.11/contribute.html index d6e17e272..23a964460 100644 --- a/docs/0.9.11/contribute.html +++ b/docs/0.9.11/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/0.9.11/deployments/deploying-to-aws.html b/docs/0.9.11/deployments/deploying-to-aws.html index d97f479b9..d1eff04ea 100644 --- a/docs/0.9.11/deployments/deploying-to-aws.html +++ b/docs/0.9.11/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ Deploying to AWS | Serverpod - + diff --git a/docs/0.9.11/deployments/general.html b/docs/0.9.11/deployments/general.html index b15efa841..d498dc84c 100644 --- a/docs/0.9.11/deployments/general.html +++ b/docs/0.9.11/deployments/general.html @@ -4,7 +4,7 @@ General notes | Serverpod - + diff --git a/docs/0.9.11/roadmap.html b/docs/0.9.11/roadmap.html index 3f63aa5e7..43d1ee81c 100644 --- a/docs/0.9.11/roadmap.html +++ b/docs/0.9.11/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/0.9.11/support.html b/docs/0.9.11/support.html index 5723094c1..732d44388 100644 --- a/docs/0.9.11/support.html +++ b/docs/0.9.11/support.html @@ -4,7 +4,7 @@ Support & community | Serverpod - + diff --git a/docs/0.9.20.html b/docs/0.9.20.html index 9ed15a6aa..9161af283 100644 --- a/docs/0.9.20.html +++ b/docs/0.9.20.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/0.9.20/capabilities.html b/docs/0.9.20/capabilities.html index aa94d68cd..68b0e29a6 100644 --- a/docs/0.9.20/capabilities.html +++ b/docs/0.9.20/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/0.9.20/concepts/authentication.html b/docs/0.9.20/concepts/authentication.html index 748bcd169..d2f896e34 100644 --- a/docs/0.9.20/concepts/authentication.html +++ b/docs/0.9.20/concepts/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/0.9.20/concepts/backward-compatibility.html b/docs/0.9.20/concepts/backward-compatibility.html index e3775725b..75bfb63a8 100644 --- a/docs/0.9.20/concepts/backward-compatibility.html +++ b/docs/0.9.20/concepts/backward-compatibility.html @@ -4,7 +4,7 @@ Backward compatibility | Serverpod - + diff --git a/docs/0.9.20/concepts/caching.html b/docs/0.9.20/concepts/caching.html index 8b9a627b6..69d2444b5 100644 --- a/docs/0.9.20/concepts/caching.html +++ b/docs/0.9.20/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/0.9.20/concepts/database-communication.html b/docs/0.9.20/concepts/database-communication.html index 799270d4c..f65cfc2f1 100644 --- a/docs/0.9.20/concepts/database-communication.html +++ b/docs/0.9.20/concepts/database-communication.html @@ -4,7 +4,7 @@ Database communication | Serverpod - + diff --git a/docs/0.9.20/concepts/file-uploads.html b/docs/0.9.20/concepts/file-uploads.html index de5a61353..60eab955f 100644 --- a/docs/0.9.20/concepts/file-uploads.html +++ b/docs/0.9.20/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/0.9.20/concepts/health-checks.html b/docs/0.9.20/concepts/health-checks.html index d049b37a6..4eb57146f 100644 --- a/docs/0.9.20/concepts/health-checks.html +++ b/docs/0.9.20/concepts/health-checks.html @@ -4,7 +4,7 @@ Health checks | Serverpod - + diff --git a/docs/0.9.20/concepts/logging.html b/docs/0.9.20/concepts/logging.html index abaab0eee..a10f3313a 100644 --- a/docs/0.9.20/concepts/logging.html +++ b/docs/0.9.20/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/0.9.20/concepts/modules.html b/docs/0.9.20/concepts/modules.html index 88c007483..b79105434 100644 --- a/docs/0.9.20/concepts/modules.html +++ b/docs/0.9.20/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/0.9.20/concepts/serialization.html b/docs/0.9.20/concepts/serialization.html index cd9dfd9d1..d8cdf95c0 100644 --- a/docs/0.9.20/concepts/serialization.html +++ b/docs/0.9.20/concepts/serialization.html @@ -4,7 +4,7 @@ Serialization | Serverpod - + diff --git a/docs/0.9.20/concepts/streams.html b/docs/0.9.20/concepts/streams.html index f311209f6..5ff4bccb5 100644 --- a/docs/0.9.20/concepts/streams.html +++ b/docs/0.9.20/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/0.9.20/concepts/webserver.html b/docs/0.9.20/concepts/webserver.html index 8a14562da..352ecfe10 100644 --- a/docs/0.9.20/concepts/webserver.html +++ b/docs/0.9.20/concepts/webserver.html @@ -4,7 +4,7 @@ Web server | Serverpod - + diff --git a/docs/0.9.20/concepts/working-with-endpoints.html b/docs/0.9.20/concepts/working-with-endpoints.html index 3d98caef4..17f3d3828 100644 --- a/docs/0.9.20/concepts/working-with-endpoints.html +++ b/docs/0.9.20/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/0.9.20/contribute.html b/docs/0.9.20/contribute.html index 13b06e26a..676b80a1d 100644 --- a/docs/0.9.20/contribute.html +++ b/docs/0.9.20/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/0.9.20/deployments/deploying-to-aws.html b/docs/0.9.20/deployments/deploying-to-aws.html index cf0034a32..2b8cb968d 100644 --- a/docs/0.9.20/deployments/deploying-to-aws.html +++ b/docs/0.9.20/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ Deploying to AWS | Serverpod - + diff --git a/docs/0.9.20/deployments/general.html b/docs/0.9.20/deployments/general.html index dd26d1f2d..a465ddefc 100644 --- a/docs/0.9.20/deployments/general.html +++ b/docs/0.9.20/deployments/general.html @@ -4,7 +4,7 @@ General notes | Serverpod - + diff --git a/docs/0.9.20/roadmap.html b/docs/0.9.20/roadmap.html index e26a60f50..674f71647 100644 --- a/docs/0.9.20/roadmap.html +++ b/docs/0.9.20/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/0.9.20/support.html b/docs/0.9.20/support.html index f0928d5e2..03df182ac 100644 --- a/docs/0.9.20/support.html +++ b/docs/0.9.20/support.html @@ -4,7 +4,7 @@ Support & community | Serverpod - + diff --git a/docs/0.9.20/tutorials.html b/docs/0.9.20/tutorials.html index 9c3618b6a..9ff2f3f7b 100644 --- a/docs/0.9.20/tutorials.html +++ b/docs/0.9.20/tutorials.html @@ -4,7 +4,7 @@ Tutorials & Examples | Serverpod - + diff --git a/docs/0.9.21.html b/docs/0.9.21.html index 7628aee01..5107d0440 100644 --- a/docs/0.9.21.html +++ b/docs/0.9.21.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/0.9.21/capabilities.html b/docs/0.9.21/capabilities.html index a8214e2e7..32be91b9f 100644 --- a/docs/0.9.21/capabilities.html +++ b/docs/0.9.21/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/0.9.21/concepts/authentication.html b/docs/0.9.21/concepts/authentication.html index 9ba3a71b7..1348b75c7 100644 --- a/docs/0.9.21/concepts/authentication.html +++ b/docs/0.9.21/concepts/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/0.9.21/concepts/backward-compatibility.html b/docs/0.9.21/concepts/backward-compatibility.html index 2719bbb72..9fe0bcda7 100644 --- a/docs/0.9.21/concepts/backward-compatibility.html +++ b/docs/0.9.21/concepts/backward-compatibility.html @@ -4,7 +4,7 @@ Backward compatibility | Serverpod - + diff --git a/docs/0.9.21/concepts/caching.html b/docs/0.9.21/concepts/caching.html index ac952a3e2..5e5e0d9e2 100644 --- a/docs/0.9.21/concepts/caching.html +++ b/docs/0.9.21/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/0.9.21/concepts/database-communication.html b/docs/0.9.21/concepts/database-communication.html index 57eac4754..b1360bbd7 100644 --- a/docs/0.9.21/concepts/database-communication.html +++ b/docs/0.9.21/concepts/database-communication.html @@ -4,7 +4,7 @@ Database communication | Serverpod - + diff --git a/docs/0.9.21/concepts/file-uploads.html b/docs/0.9.21/concepts/file-uploads.html index 4ed54280a..bb0a5ab56 100644 --- a/docs/0.9.21/concepts/file-uploads.html +++ b/docs/0.9.21/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/0.9.21/concepts/health-checks.html b/docs/0.9.21/concepts/health-checks.html index 3d9eb57c9..4f5ccf3af 100644 --- a/docs/0.9.21/concepts/health-checks.html +++ b/docs/0.9.21/concepts/health-checks.html @@ -4,7 +4,7 @@ Health checks | Serverpod - + diff --git a/docs/0.9.21/concepts/logging.html b/docs/0.9.21/concepts/logging.html index b28acb647..b1890e0a9 100644 --- a/docs/0.9.21/concepts/logging.html +++ b/docs/0.9.21/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/0.9.21/concepts/modules.html b/docs/0.9.21/concepts/modules.html index 131531df7..5844356f3 100644 --- a/docs/0.9.21/concepts/modules.html +++ b/docs/0.9.21/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/0.9.21/concepts/serialization.html b/docs/0.9.21/concepts/serialization.html index 5e328e496..e74a94be3 100644 --- a/docs/0.9.21/concepts/serialization.html +++ b/docs/0.9.21/concepts/serialization.html @@ -4,7 +4,7 @@ Serialization | Serverpod - + diff --git a/docs/0.9.21/concepts/streams.html b/docs/0.9.21/concepts/streams.html index 10f5d1d73..440ec9774 100644 --- a/docs/0.9.21/concepts/streams.html +++ b/docs/0.9.21/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/0.9.21/concepts/webserver.html b/docs/0.9.21/concepts/webserver.html index 60d0ab5b0..dad38444f 100644 --- a/docs/0.9.21/concepts/webserver.html +++ b/docs/0.9.21/concepts/webserver.html @@ -4,7 +4,7 @@ Web server | Serverpod - + diff --git a/docs/0.9.21/concepts/working-with-endpoints.html b/docs/0.9.21/concepts/working-with-endpoints.html index 8c4c956c6..17f9c5b88 100644 --- a/docs/0.9.21/concepts/working-with-endpoints.html +++ b/docs/0.9.21/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/0.9.21/contribute.html b/docs/0.9.21/contribute.html index 1b5909fdf..9869ba0e3 100644 --- a/docs/0.9.21/contribute.html +++ b/docs/0.9.21/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/0.9.21/deployments/deploying-to-aws.html b/docs/0.9.21/deployments/deploying-to-aws.html index 89a91ba7e..a4927c36a 100644 --- a/docs/0.9.21/deployments/deploying-to-aws.html +++ b/docs/0.9.21/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ Deploying to AWS | Serverpod - + diff --git a/docs/0.9.21/deployments/general.html b/docs/0.9.21/deployments/general.html index 3151fb44a..0ecb472da 100644 --- a/docs/0.9.21/deployments/general.html +++ b/docs/0.9.21/deployments/general.html @@ -4,7 +4,7 @@ General notes | Serverpod - + diff --git a/docs/0.9.21/roadmap.html b/docs/0.9.21/roadmap.html index 39386e58c..414f57595 100644 --- a/docs/0.9.21/roadmap.html +++ b/docs/0.9.21/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/0.9.21/support.html b/docs/0.9.21/support.html index e89908d5b..bc5731ee9 100644 --- a/docs/0.9.21/support.html +++ b/docs/0.9.21/support.html @@ -4,7 +4,7 @@ Support & community | Serverpod - + diff --git a/docs/0.9.21/tutorials.html b/docs/0.9.21/tutorials.html index 791ad14bc..0b6638899 100644 --- a/docs/0.9.21/tutorials.html +++ b/docs/0.9.21/tutorials.html @@ -4,7 +4,7 @@ Tutorials & Examples | Serverpod - + diff --git a/docs/0.9.22.html b/docs/0.9.22.html index db6698066..10cd53531 100644 --- a/docs/0.9.22.html +++ b/docs/0.9.22.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/0.9.22/capabilities.html b/docs/0.9.22/capabilities.html index 07f0c8f8d..8cf6ca587 100644 --- a/docs/0.9.22/capabilities.html +++ b/docs/0.9.22/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/0.9.22/concepts/authentication.html b/docs/0.9.22/concepts/authentication.html index 46ffbe951..0c3733c71 100644 --- a/docs/0.9.22/concepts/authentication.html +++ b/docs/0.9.22/concepts/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/0.9.22/concepts/backward-compatibility.html b/docs/0.9.22/concepts/backward-compatibility.html index 3287ffee5..b55d3f54c 100644 --- a/docs/0.9.22/concepts/backward-compatibility.html +++ b/docs/0.9.22/concepts/backward-compatibility.html @@ -4,7 +4,7 @@ Backward compatibility | Serverpod - + diff --git a/docs/0.9.22/concepts/caching.html b/docs/0.9.22/concepts/caching.html index 9b01dd1e8..4cafe4739 100644 --- a/docs/0.9.22/concepts/caching.html +++ b/docs/0.9.22/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/0.9.22/concepts/database-communication.html b/docs/0.9.22/concepts/database-communication.html index dd478942d..7db45de43 100644 --- a/docs/0.9.22/concepts/database-communication.html +++ b/docs/0.9.22/concepts/database-communication.html @@ -4,7 +4,7 @@ Database communication | Serverpod - + diff --git a/docs/0.9.22/concepts/file-uploads.html b/docs/0.9.22/concepts/file-uploads.html index ab2653acb..bbc1e008a 100644 --- a/docs/0.9.22/concepts/file-uploads.html +++ b/docs/0.9.22/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/0.9.22/concepts/health-checks.html b/docs/0.9.22/concepts/health-checks.html index 4ae853f9d..8c6723714 100644 --- a/docs/0.9.22/concepts/health-checks.html +++ b/docs/0.9.22/concepts/health-checks.html @@ -4,7 +4,7 @@ Health checks | Serverpod - + diff --git a/docs/0.9.22/concepts/logging.html b/docs/0.9.22/concepts/logging.html index 76fd8a58b..77aa9f15a 100644 --- a/docs/0.9.22/concepts/logging.html +++ b/docs/0.9.22/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/0.9.22/concepts/modules.html b/docs/0.9.22/concepts/modules.html index 489e9a74c..d8aa2879e 100644 --- a/docs/0.9.22/concepts/modules.html +++ b/docs/0.9.22/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/0.9.22/concepts/serialization.html b/docs/0.9.22/concepts/serialization.html index eac181730..483409fd3 100644 --- a/docs/0.9.22/concepts/serialization.html +++ b/docs/0.9.22/concepts/serialization.html @@ -4,7 +4,7 @@ Serialization | Serverpod - + diff --git a/docs/0.9.22/concepts/streams.html b/docs/0.9.22/concepts/streams.html index e957d6080..317d59b55 100644 --- a/docs/0.9.22/concepts/streams.html +++ b/docs/0.9.22/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/0.9.22/concepts/webserver.html b/docs/0.9.22/concepts/webserver.html index b7be5fe9a..a1b7c3fd5 100644 --- a/docs/0.9.22/concepts/webserver.html +++ b/docs/0.9.22/concepts/webserver.html @@ -4,7 +4,7 @@ Web server | Serverpod - + diff --git a/docs/0.9.22/concepts/working-with-endpoints.html b/docs/0.9.22/concepts/working-with-endpoints.html index 724455451..316f4b28d 100644 --- a/docs/0.9.22/concepts/working-with-endpoints.html +++ b/docs/0.9.22/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/0.9.22/contribute.html b/docs/0.9.22/contribute.html index e4e3345d4..7c513f254 100644 --- a/docs/0.9.22/contribute.html +++ b/docs/0.9.22/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/0.9.22/deployments/deploying-to-aws.html b/docs/0.9.22/deployments/deploying-to-aws.html index 672345b0c..07c5b4692 100644 --- a/docs/0.9.22/deployments/deploying-to-aws.html +++ b/docs/0.9.22/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ Deploying to AWS | Serverpod - + diff --git a/docs/0.9.22/deployments/general.html b/docs/0.9.22/deployments/general.html index 1b8effeef..cad9a25b1 100644 --- a/docs/0.9.22/deployments/general.html +++ b/docs/0.9.22/deployments/general.html @@ -4,7 +4,7 @@ General notes | Serverpod - + diff --git a/docs/0.9.22/roadmap.html b/docs/0.9.22/roadmap.html index 53f000581..21efb53b8 100644 --- a/docs/0.9.22/roadmap.html +++ b/docs/0.9.22/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/0.9.22/support.html b/docs/0.9.22/support.html index 9da9904f4..9fae462ee 100644 --- a/docs/0.9.22/support.html +++ b/docs/0.9.22/support.html @@ -4,7 +4,7 @@ Support & community | Serverpod - + diff --git a/docs/0.9.22/tutorials.html b/docs/0.9.22/tutorials.html index 7bf0a0812..7b2c91baa 100644 --- a/docs/0.9.22/tutorials.html +++ b/docs/0.9.22/tutorials.html @@ -4,7 +4,7 @@ Tutorials & Examples | Serverpod - + diff --git a/docs/0.9.5.html b/docs/0.9.5.html index d18f2d08d..119947c8a 100644 --- a/docs/0.9.5.html +++ b/docs/0.9.5.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/0.9.5/capabilities.html b/docs/0.9.5/capabilities.html index ae018b427..399e45cd5 100644 --- a/docs/0.9.5/capabilities.html +++ b/docs/0.9.5/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/0.9.5/concepts/authentication.html b/docs/0.9.5/concepts/authentication.html index 8137ce850..13612887e 100644 --- a/docs/0.9.5/concepts/authentication.html +++ b/docs/0.9.5/concepts/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/0.9.5/concepts/caching.html b/docs/0.9.5/concepts/caching.html index 36e8fbb6b..9649c4da6 100644 --- a/docs/0.9.5/concepts/caching.html +++ b/docs/0.9.5/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/0.9.5/concepts/database-communication.html b/docs/0.9.5/concepts/database-communication.html index 3493c9ce2..47cc3d828 100644 --- a/docs/0.9.5/concepts/database-communication.html +++ b/docs/0.9.5/concepts/database-communication.html @@ -4,7 +4,7 @@ Database communication | Serverpod - + diff --git a/docs/0.9.5/concepts/file-uploads.html b/docs/0.9.5/concepts/file-uploads.html index bb0b9e531..76d11cd56 100644 --- a/docs/0.9.5/concepts/file-uploads.html +++ b/docs/0.9.5/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/0.9.5/concepts/logging.html b/docs/0.9.5/concepts/logging.html index 48563f6e5..807ed6612 100644 --- a/docs/0.9.5/concepts/logging.html +++ b/docs/0.9.5/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/0.9.5/concepts/modules.html b/docs/0.9.5/concepts/modules.html index 029116eb1..49eebc90f 100644 --- a/docs/0.9.5/concepts/modules.html +++ b/docs/0.9.5/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/0.9.5/concepts/serialization.html b/docs/0.9.5/concepts/serialization.html index 8a2dda0ad..dc29103f2 100644 --- a/docs/0.9.5/concepts/serialization.html +++ b/docs/0.9.5/concepts/serialization.html @@ -4,7 +4,7 @@ Serialization | Serverpod - + diff --git a/docs/0.9.5/concepts/streams.html b/docs/0.9.5/concepts/streams.html index 5f9de8f18..6304c7942 100644 --- a/docs/0.9.5/concepts/streams.html +++ b/docs/0.9.5/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/0.9.5/concepts/working-with-endpoints.html b/docs/0.9.5/concepts/working-with-endpoints.html index 7a574c705..f5c7468b6 100644 --- a/docs/0.9.5/concepts/working-with-endpoints.html +++ b/docs/0.9.5/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/0.9.5/contribute.html b/docs/0.9.5/contribute.html index 57c6857c3..c48397918 100644 --- a/docs/0.9.5/contribute.html +++ b/docs/0.9.5/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/0.9.5/deployments/general.html b/docs/0.9.5/deployments/general.html index 222322a19..3624301ac 100644 --- a/docs/0.9.5/deployments/general.html +++ b/docs/0.9.5/deployments/general.html @@ -4,7 +4,7 @@ General notes | Serverpod - + diff --git a/docs/0.9.5/roadmap.html b/docs/0.9.5/roadmap.html index 09e082357..77d5dc7ed 100644 --- a/docs/0.9.5/roadmap.html +++ b/docs/0.9.5/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/0.9.6.html b/docs/0.9.6.html index efce39433..d11195daa 100644 --- a/docs/0.9.6.html +++ b/docs/0.9.6.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/0.9.6/capabilities.html b/docs/0.9.6/capabilities.html index 0bfaf1cbe..b903e3036 100644 --- a/docs/0.9.6/capabilities.html +++ b/docs/0.9.6/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/0.9.6/concepts/authentication.html b/docs/0.9.6/concepts/authentication.html index 182ebc9d4..be8320184 100644 --- a/docs/0.9.6/concepts/authentication.html +++ b/docs/0.9.6/concepts/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/0.9.6/concepts/caching.html b/docs/0.9.6/concepts/caching.html index 45bebe68c..fb466b2de 100644 --- a/docs/0.9.6/concepts/caching.html +++ b/docs/0.9.6/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/0.9.6/concepts/database-communication.html b/docs/0.9.6/concepts/database-communication.html index 7e436884e..06782874e 100644 --- a/docs/0.9.6/concepts/database-communication.html +++ b/docs/0.9.6/concepts/database-communication.html @@ -4,7 +4,7 @@ Database communication | Serverpod - + diff --git a/docs/0.9.6/concepts/file-uploads.html b/docs/0.9.6/concepts/file-uploads.html index ccdb808bb..2ed9d5637 100644 --- a/docs/0.9.6/concepts/file-uploads.html +++ b/docs/0.9.6/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/0.9.6/concepts/logging.html b/docs/0.9.6/concepts/logging.html index a987c1a38..5b6b6316d 100644 --- a/docs/0.9.6/concepts/logging.html +++ b/docs/0.9.6/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/0.9.6/concepts/modules.html b/docs/0.9.6/concepts/modules.html index 361a92762..89c62d596 100644 --- a/docs/0.9.6/concepts/modules.html +++ b/docs/0.9.6/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/0.9.6/concepts/serialization.html b/docs/0.9.6/concepts/serialization.html index 212ea77bb..b25e51bff 100644 --- a/docs/0.9.6/concepts/serialization.html +++ b/docs/0.9.6/concepts/serialization.html @@ -4,7 +4,7 @@ Serialization | Serverpod - + diff --git a/docs/0.9.6/concepts/streams.html b/docs/0.9.6/concepts/streams.html index e5ef54ae3..6b5e0089e 100644 --- a/docs/0.9.6/concepts/streams.html +++ b/docs/0.9.6/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/0.9.6/concepts/working-with-endpoints.html b/docs/0.9.6/concepts/working-with-endpoints.html index afd5bb3e9..c1cd7c2f7 100644 --- a/docs/0.9.6/concepts/working-with-endpoints.html +++ b/docs/0.9.6/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/0.9.6/contribute.html b/docs/0.9.6/contribute.html index 64a4a943e..f67bc906f 100644 --- a/docs/0.9.6/contribute.html +++ b/docs/0.9.6/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/0.9.6/deployments/general.html b/docs/0.9.6/deployments/general.html index bcfd6711b..a495f553e 100644 --- a/docs/0.9.6/deployments/general.html +++ b/docs/0.9.6/deployments/general.html @@ -4,7 +4,7 @@ General notes | Serverpod - + diff --git a/docs/0.9.6/roadmap.html b/docs/0.9.6/roadmap.html index 65f0cf6fc..054d2f9f4 100644 --- a/docs/0.9.6/roadmap.html +++ b/docs/0.9.6/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/0.9.7.html b/docs/0.9.7.html index 6d7ca598c..520e86c27 100644 --- a/docs/0.9.7.html +++ b/docs/0.9.7.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/0.9.7/capabilities.html b/docs/0.9.7/capabilities.html index 50a959aa9..7f6ee7ff0 100644 --- a/docs/0.9.7/capabilities.html +++ b/docs/0.9.7/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/0.9.7/concepts/authentication.html b/docs/0.9.7/concepts/authentication.html index ced47a176..114f39059 100644 --- a/docs/0.9.7/concepts/authentication.html +++ b/docs/0.9.7/concepts/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/0.9.7/concepts/caching.html b/docs/0.9.7/concepts/caching.html index aa5a7f29d..4b42f3d4d 100644 --- a/docs/0.9.7/concepts/caching.html +++ b/docs/0.9.7/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/0.9.7/concepts/database-communication.html b/docs/0.9.7/concepts/database-communication.html index 724989415..4126f9d60 100644 --- a/docs/0.9.7/concepts/database-communication.html +++ b/docs/0.9.7/concepts/database-communication.html @@ -4,7 +4,7 @@ Database communication | Serverpod - + diff --git a/docs/0.9.7/concepts/file-uploads.html b/docs/0.9.7/concepts/file-uploads.html index 83441c713..a6342f22b 100644 --- a/docs/0.9.7/concepts/file-uploads.html +++ b/docs/0.9.7/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/0.9.7/concepts/logging.html b/docs/0.9.7/concepts/logging.html index ce2005b8d..609b9d5a0 100644 --- a/docs/0.9.7/concepts/logging.html +++ b/docs/0.9.7/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/0.9.7/concepts/modules.html b/docs/0.9.7/concepts/modules.html index fc6f77b28..cbe82514e 100644 --- a/docs/0.9.7/concepts/modules.html +++ b/docs/0.9.7/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/0.9.7/concepts/serialization.html b/docs/0.9.7/concepts/serialization.html index 700da2fcf..11a6976a2 100644 --- a/docs/0.9.7/concepts/serialization.html +++ b/docs/0.9.7/concepts/serialization.html @@ -4,7 +4,7 @@ Serialization | Serverpod - + diff --git a/docs/0.9.7/concepts/streams.html b/docs/0.9.7/concepts/streams.html index 4b006052a..a3b0bc55a 100644 --- a/docs/0.9.7/concepts/streams.html +++ b/docs/0.9.7/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/0.9.7/concepts/working-with-endpoints.html b/docs/0.9.7/concepts/working-with-endpoints.html index f20f1c233..58fadb229 100644 --- a/docs/0.9.7/concepts/working-with-endpoints.html +++ b/docs/0.9.7/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/0.9.7/contribute.html b/docs/0.9.7/contribute.html index 241f22cec..f0b6827c4 100644 --- a/docs/0.9.7/contribute.html +++ b/docs/0.9.7/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/0.9.7/deployments/general.html b/docs/0.9.7/deployments/general.html index a6842997b..85d194baf 100644 --- a/docs/0.9.7/deployments/general.html +++ b/docs/0.9.7/deployments/general.html @@ -4,7 +4,7 @@ General notes | Serverpod - + diff --git a/docs/0.9.7/roadmap.html b/docs/0.9.7/roadmap.html index 8cc861fc1..658be86ad 100644 --- a/docs/0.9.7/roadmap.html +++ b/docs/0.9.7/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/0.9.7/support.html b/docs/0.9.7/support.html index 9dd2e8d9b..edad2e3af 100644 --- a/docs/0.9.7/support.html +++ b/docs/0.9.7/support.html @@ -4,7 +4,7 @@ Support | Serverpod - + diff --git a/docs/0.9.8.html b/docs/0.9.8.html index f9599fccd..5b317bc68 100644 --- a/docs/0.9.8.html +++ b/docs/0.9.8.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/0.9.8/capabilities.html b/docs/0.9.8/capabilities.html index 32d8f5a87..231cfe549 100644 --- a/docs/0.9.8/capabilities.html +++ b/docs/0.9.8/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/0.9.8/concepts/authentication.html b/docs/0.9.8/concepts/authentication.html index 846c13e1d..e81d378e7 100644 --- a/docs/0.9.8/concepts/authentication.html +++ b/docs/0.9.8/concepts/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/0.9.8/concepts/caching.html b/docs/0.9.8/concepts/caching.html index ccf347c45..5aec2cb59 100644 --- a/docs/0.9.8/concepts/caching.html +++ b/docs/0.9.8/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/0.9.8/concepts/database-communication.html b/docs/0.9.8/concepts/database-communication.html index d9e155e92..a0cd1bfe0 100644 --- a/docs/0.9.8/concepts/database-communication.html +++ b/docs/0.9.8/concepts/database-communication.html @@ -4,7 +4,7 @@ Database communication | Serverpod - + diff --git a/docs/0.9.8/concepts/file-uploads.html b/docs/0.9.8/concepts/file-uploads.html index d38000701..fecc0c196 100644 --- a/docs/0.9.8/concepts/file-uploads.html +++ b/docs/0.9.8/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/0.9.8/concepts/logging.html b/docs/0.9.8/concepts/logging.html index fcaf0a3e4..9f9a0bf9f 100644 --- a/docs/0.9.8/concepts/logging.html +++ b/docs/0.9.8/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/0.9.8/concepts/modules.html b/docs/0.9.8/concepts/modules.html index b7b4b3e1a..fce3d92b8 100644 --- a/docs/0.9.8/concepts/modules.html +++ b/docs/0.9.8/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/0.9.8/concepts/serialization.html b/docs/0.9.8/concepts/serialization.html index fe311de76..68fe27c24 100644 --- a/docs/0.9.8/concepts/serialization.html +++ b/docs/0.9.8/concepts/serialization.html @@ -4,7 +4,7 @@ Serialization | Serverpod - + diff --git a/docs/0.9.8/concepts/streams.html b/docs/0.9.8/concepts/streams.html index 2172b9ee0..091aab0e3 100644 --- a/docs/0.9.8/concepts/streams.html +++ b/docs/0.9.8/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/0.9.8/concepts/working-with-endpoints.html b/docs/0.9.8/concepts/working-with-endpoints.html index 8e35e899b..4901e641c 100644 --- a/docs/0.9.8/concepts/working-with-endpoints.html +++ b/docs/0.9.8/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/0.9.8/contribute.html b/docs/0.9.8/contribute.html index 306e0ca80..6f63ca208 100644 --- a/docs/0.9.8/contribute.html +++ b/docs/0.9.8/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/0.9.8/deployments/deploying-to-aws.html b/docs/0.9.8/deployments/deploying-to-aws.html index 179875008..bb5f6af00 100644 --- a/docs/0.9.8/deployments/deploying-to-aws.html +++ b/docs/0.9.8/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ Deploying to AWS | Serverpod - + diff --git a/docs/0.9.8/deployments/general.html b/docs/0.9.8/deployments/general.html index b941da7da..565ff34d4 100644 --- a/docs/0.9.8/deployments/general.html +++ b/docs/0.9.8/deployments/general.html @@ -4,7 +4,7 @@ General notes | Serverpod - + diff --git a/docs/0.9.8/roadmap.html b/docs/0.9.8/roadmap.html index 6f07ed2ac..c05128c08 100644 --- a/docs/0.9.8/roadmap.html +++ b/docs/0.9.8/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/0.9.8/support.html b/docs/0.9.8/support.html index c74a538ac..d61243c2f 100644 --- a/docs/0.9.8/support.html +++ b/docs/0.9.8/support.html @@ -4,7 +4,7 @@ Support | Serverpod - + diff --git a/docs/0.9.9.html b/docs/0.9.9.html index b0da18deb..9ea41aa30 100644 --- a/docs/0.9.9.html +++ b/docs/0.9.9.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/0.9.9/capabilities.html b/docs/0.9.9/capabilities.html index f89ba3240..771b5d9dc 100644 --- a/docs/0.9.9/capabilities.html +++ b/docs/0.9.9/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/0.9.9/concepts/authentication.html b/docs/0.9.9/concepts/authentication.html index 6f19895e0..4bdd0543a 100644 --- a/docs/0.9.9/concepts/authentication.html +++ b/docs/0.9.9/concepts/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/0.9.9/concepts/caching.html b/docs/0.9.9/concepts/caching.html index e6c71e813..fb3819074 100644 --- a/docs/0.9.9/concepts/caching.html +++ b/docs/0.9.9/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/0.9.9/concepts/database-communication.html b/docs/0.9.9/concepts/database-communication.html index 831870362..db2ca7888 100644 --- a/docs/0.9.9/concepts/database-communication.html +++ b/docs/0.9.9/concepts/database-communication.html @@ -4,7 +4,7 @@ Database communication | Serverpod - + diff --git a/docs/0.9.9/concepts/file-uploads.html b/docs/0.9.9/concepts/file-uploads.html index a70904501..cc6fa4cbe 100644 --- a/docs/0.9.9/concepts/file-uploads.html +++ b/docs/0.9.9/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/0.9.9/concepts/logging.html b/docs/0.9.9/concepts/logging.html index a2889c657..3228af780 100644 --- a/docs/0.9.9/concepts/logging.html +++ b/docs/0.9.9/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/0.9.9/concepts/modules.html b/docs/0.9.9/concepts/modules.html index 03d95c344..bc8df1845 100644 --- a/docs/0.9.9/concepts/modules.html +++ b/docs/0.9.9/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/0.9.9/concepts/serialization.html b/docs/0.9.9/concepts/serialization.html index ed58b9e52..179200a67 100644 --- a/docs/0.9.9/concepts/serialization.html +++ b/docs/0.9.9/concepts/serialization.html @@ -4,7 +4,7 @@ Serialization | Serverpod - + diff --git a/docs/0.9.9/concepts/streams.html b/docs/0.9.9/concepts/streams.html index b2ac399c2..651d9b01f 100644 --- a/docs/0.9.9/concepts/streams.html +++ b/docs/0.9.9/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/0.9.9/concepts/webserver.html b/docs/0.9.9/concepts/webserver.html index f5d57b332..f5ec28d6a 100644 --- a/docs/0.9.9/concepts/webserver.html +++ b/docs/0.9.9/concepts/webserver.html @@ -4,7 +4,7 @@ Web server | Serverpod - + diff --git a/docs/0.9.9/concepts/working-with-endpoints.html b/docs/0.9.9/concepts/working-with-endpoints.html index 9437d0921..b858fc9e4 100644 --- a/docs/0.9.9/concepts/working-with-endpoints.html +++ b/docs/0.9.9/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/0.9.9/contribute.html b/docs/0.9.9/contribute.html index b0f50b6b6..03159c921 100644 --- a/docs/0.9.9/contribute.html +++ b/docs/0.9.9/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/0.9.9/deployments/deploying-to-aws.html b/docs/0.9.9/deployments/deploying-to-aws.html index ab49a51d0..ce5e6beb6 100644 --- a/docs/0.9.9/deployments/deploying-to-aws.html +++ b/docs/0.9.9/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ Deploying to AWS | Serverpod - + diff --git a/docs/0.9.9/deployments/general.html b/docs/0.9.9/deployments/general.html index 5ad5521a2..2d64c22e1 100644 --- a/docs/0.9.9/deployments/general.html +++ b/docs/0.9.9/deployments/general.html @@ -4,7 +4,7 @@ General notes | Serverpod - + diff --git a/docs/0.9.9/roadmap.html b/docs/0.9.9/roadmap.html index 1264a2418..89b956d47 100644 --- a/docs/0.9.9/roadmap.html +++ b/docs/0.9.9/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/0.9.9/support.html b/docs/0.9.9/support.html index ec52ce34d..89d7ac218 100644 --- a/docs/0.9.9/support.html +++ b/docs/0.9.9/support.html @@ -4,7 +4,7 @@ Support & community | Serverpod - + diff --git a/docs/1.0.0.html b/docs/1.0.0.html index 9fd77389a..37f0bc28a 100644 --- a/docs/1.0.0.html +++ b/docs/1.0.0.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/1.0.0/capabilities.html b/docs/1.0.0/capabilities.html index 0372654bd..e72204a30 100644 --- a/docs/1.0.0/capabilities.html +++ b/docs/1.0.0/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/1.0.0/concepts/authentication.html b/docs/1.0.0/concepts/authentication.html index fbd9d895a..572cb3247 100644 --- a/docs/1.0.0/concepts/authentication.html +++ b/docs/1.0.0/concepts/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/1.0.0/concepts/backward-compatibility.html b/docs/1.0.0/concepts/backward-compatibility.html index 495b2b348..b2d27b056 100644 --- a/docs/1.0.0/concepts/backward-compatibility.html +++ b/docs/1.0.0/concepts/backward-compatibility.html @@ -4,7 +4,7 @@ Backward compatibility | Serverpod - + diff --git a/docs/1.0.0/concepts/caching.html b/docs/1.0.0/concepts/caching.html index dc96f5d07..0cf2ed9a5 100644 --- a/docs/1.0.0/concepts/caching.html +++ b/docs/1.0.0/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/1.0.0/concepts/database-communication.html b/docs/1.0.0/concepts/database-communication.html index c266be420..7615a3bc1 100644 --- a/docs/1.0.0/concepts/database-communication.html +++ b/docs/1.0.0/concepts/database-communication.html @@ -4,7 +4,7 @@ Database communication | Serverpod - + diff --git a/docs/1.0.0/concepts/file-uploads.html b/docs/1.0.0/concepts/file-uploads.html index a621a3ccd..5d8e994ec 100644 --- a/docs/1.0.0/concepts/file-uploads.html +++ b/docs/1.0.0/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/1.0.0/concepts/health-checks.html b/docs/1.0.0/concepts/health-checks.html index a3f5f1728..ebf6b2eed 100644 --- a/docs/1.0.0/concepts/health-checks.html +++ b/docs/1.0.0/concepts/health-checks.html @@ -4,7 +4,7 @@ Health checks | Serverpod - + diff --git a/docs/1.0.0/concepts/logging.html b/docs/1.0.0/concepts/logging.html index c3bcc2b19..532d91e5c 100644 --- a/docs/1.0.0/concepts/logging.html +++ b/docs/1.0.0/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/1.0.0/concepts/modules.html b/docs/1.0.0/concepts/modules.html index c3eea0890..2074bb114 100644 --- a/docs/1.0.0/concepts/modules.html +++ b/docs/1.0.0/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/1.0.0/concepts/serialization.html b/docs/1.0.0/concepts/serialization.html index 4353c1daa..f57c4cf3f 100644 --- a/docs/1.0.0/concepts/serialization.html +++ b/docs/1.0.0/concepts/serialization.html @@ -4,7 +4,7 @@ Serialization | Serverpod - + diff --git a/docs/1.0.0/concepts/streams.html b/docs/1.0.0/concepts/streams.html index 50efc62ba..a0a461d84 100644 --- a/docs/1.0.0/concepts/streams.html +++ b/docs/1.0.0/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/1.0.0/concepts/webserver.html b/docs/1.0.0/concepts/webserver.html index 3413c1b55..06a63a368 100644 --- a/docs/1.0.0/concepts/webserver.html +++ b/docs/1.0.0/concepts/webserver.html @@ -4,7 +4,7 @@ Web server | Serverpod - + diff --git a/docs/1.0.0/concepts/working-with-endpoints.html b/docs/1.0.0/concepts/working-with-endpoints.html index f9b475d77..c6478eea4 100644 --- a/docs/1.0.0/concepts/working-with-endpoints.html +++ b/docs/1.0.0/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/1.0.0/contribute.html b/docs/1.0.0/contribute.html index ed37f4441..2121ddd39 100644 --- a/docs/1.0.0/contribute.html +++ b/docs/1.0.0/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/1.0.0/deployments/deploying-to-aws.html b/docs/1.0.0/deployments/deploying-to-aws.html index 8214ceca5..f5a2be433 100644 --- a/docs/1.0.0/deployments/deploying-to-aws.html +++ b/docs/1.0.0/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ Deploying to AWS | Serverpod - + diff --git a/docs/1.0.0/deployments/general.html b/docs/1.0.0/deployments/general.html index d3c284e9f..90329db20 100644 --- a/docs/1.0.0/deployments/general.html +++ b/docs/1.0.0/deployments/general.html @@ -4,7 +4,7 @@ General notes | Serverpod - + diff --git a/docs/1.0.0/roadmap.html b/docs/1.0.0/roadmap.html index cc371a191..2c6cd56d9 100644 --- a/docs/1.0.0/roadmap.html +++ b/docs/1.0.0/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/1.0.0/support.html b/docs/1.0.0/support.html index 8a7b0f633..aa9b186ae 100644 --- a/docs/1.0.0/support.html +++ b/docs/1.0.0/support.html @@ -4,7 +4,7 @@ Support & community | Serverpod - + diff --git a/docs/1.0.0/tutorials.html b/docs/1.0.0/tutorials.html index 0eb347eb3..e4c57e823 100644 --- a/docs/1.0.0/tutorials.html +++ b/docs/1.0.0/tutorials.html @@ -4,7 +4,7 @@ Tutorials & Examples | Serverpod - + diff --git a/docs/1.1.0.html b/docs/1.1.0.html index cce907a64..024747619 100644 --- a/docs/1.1.0.html +++ b/docs/1.1.0.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/1.1.0/capabilities.html b/docs/1.1.0/capabilities.html index 163ebf217..acd1c0b23 100644 --- a/docs/1.1.0/capabilities.html +++ b/docs/1.1.0/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/1.1.0/concepts/authentication.html b/docs/1.1.0/concepts/authentication.html index 339e3c9fb..83a1fead0 100644 --- a/docs/1.1.0/concepts/authentication.html +++ b/docs/1.1.0/concepts/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/1.1.0/concepts/backward-compatibility.html b/docs/1.1.0/concepts/backward-compatibility.html index e94bc5d55..adf78a6bf 100644 --- a/docs/1.1.0/concepts/backward-compatibility.html +++ b/docs/1.1.0/concepts/backward-compatibility.html @@ -4,7 +4,7 @@ Backward compatibility | Serverpod - + diff --git a/docs/1.1.0/concepts/caching.html b/docs/1.1.0/concepts/caching.html index 4d7601d04..6b1b4b4dd 100644 --- a/docs/1.1.0/concepts/caching.html +++ b/docs/1.1.0/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/1.1.0/concepts/database-communication.html b/docs/1.1.0/concepts/database-communication.html index 11e2757f5..cc522be0c 100644 --- a/docs/1.1.0/concepts/database-communication.html +++ b/docs/1.1.0/concepts/database-communication.html @@ -4,7 +4,7 @@ Database communication | Serverpod - + diff --git a/docs/1.1.0/concepts/exceptions.html b/docs/1.1.0/concepts/exceptions.html index 5b68bc4a5..691823725 100644 --- a/docs/1.1.0/concepts/exceptions.html +++ b/docs/1.1.0/concepts/exceptions.html @@ -4,7 +4,7 @@ Error handling and exceptions | Serverpod - + diff --git a/docs/1.1.0/concepts/file-uploads.html b/docs/1.1.0/concepts/file-uploads.html index 86baa39a7..e9507c6b6 100644 --- a/docs/1.1.0/concepts/file-uploads.html +++ b/docs/1.1.0/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/1.1.0/concepts/health-checks.html b/docs/1.1.0/concepts/health-checks.html index 89ab1d736..fa9cb0736 100644 --- a/docs/1.1.0/concepts/health-checks.html +++ b/docs/1.1.0/concepts/health-checks.html @@ -4,7 +4,7 @@ Health checks | Serverpod - + diff --git a/docs/1.1.0/concepts/logging.html b/docs/1.1.0/concepts/logging.html index 5e9f55abc..c90018b98 100644 --- a/docs/1.1.0/concepts/logging.html +++ b/docs/1.1.0/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/1.1.0/concepts/modules.html b/docs/1.1.0/concepts/modules.html index 1bd4a6bb8..e36ef3b0e 100644 --- a/docs/1.1.0/concepts/modules.html +++ b/docs/1.1.0/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/1.1.0/concepts/serialization.html b/docs/1.1.0/concepts/serialization.html index fccb2293c..5fb042e29 100644 --- a/docs/1.1.0/concepts/serialization.html +++ b/docs/1.1.0/concepts/serialization.html @@ -4,7 +4,7 @@ Serialization | Serverpod - + diff --git a/docs/1.1.0/concepts/sessions.html b/docs/1.1.0/concepts/sessions.html index e6fcbee90..46f68a0bd 100644 --- a/docs/1.1.0/concepts/sessions.html +++ b/docs/1.1.0/concepts/sessions.html @@ -4,7 +4,7 @@ Sessions | Serverpod - + diff --git a/docs/1.1.0/concepts/streams.html b/docs/1.1.0/concepts/streams.html index 615006e54..9aa221403 100644 --- a/docs/1.1.0/concepts/streams.html +++ b/docs/1.1.0/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/1.1.0/concepts/webserver.html b/docs/1.1.0/concepts/webserver.html index e5c13bda3..ac751324e 100644 --- a/docs/1.1.0/concepts/webserver.html +++ b/docs/1.1.0/concepts/webserver.html @@ -4,7 +4,7 @@ Web server | Serverpod - + diff --git a/docs/1.1.0/concepts/working-with-endpoints.html b/docs/1.1.0/concepts/working-with-endpoints.html index 96cdce98f..f9c8d1604 100644 --- a/docs/1.1.0/concepts/working-with-endpoints.html +++ b/docs/1.1.0/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/1.1.0/contribute.html b/docs/1.1.0/contribute.html index 4566de0ff..90e3d362c 100644 --- a/docs/1.1.0/contribute.html +++ b/docs/1.1.0/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/1.1.0/deployments/deploying-to-aws.html b/docs/1.1.0/deployments/deploying-to-aws.html index 4f3d42eb8..4d72e6192 100644 --- a/docs/1.1.0/deployments/deploying-to-aws.html +++ b/docs/1.1.0/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ AWS EC2 with Terraform | Serverpod - + diff --git a/docs/1.1.0/deployments/deploying-to-gce-terraform.html b/docs/1.1.0/deployments/deploying-to-gce-terraform.html index b5b210eb9..e53310bf0 100644 --- a/docs/1.1.0/deployments/deploying-to-gce-terraform.html +++ b/docs/1.1.0/deployments/deploying-to-gce-terraform.html @@ -4,7 +4,7 @@ Google Cloud Engine with Terraform | Serverpod - + diff --git a/docs/1.1.0/deployments/deploying-to-gcr-console.html b/docs/1.1.0/deployments/deploying-to-gcr-console.html index 071e659a4..eb6c82c1b 100644 --- a/docs/1.1.0/deployments/deploying-to-gcr-console.html +++ b/docs/1.1.0/deployments/deploying-to-gcr-console.html @@ -4,7 +4,7 @@ Google Cloud Run with CGP Console | Serverpod - + diff --git a/docs/1.1.0/deployments/deployment-strategy.html b/docs/1.1.0/deployments/deployment-strategy.html index 3a45f1fc2..2def54784 100644 --- a/docs/1.1.0/deployments/deployment-strategy.html +++ b/docs/1.1.0/deployments/deployment-strategy.html @@ -4,7 +4,7 @@ Choosing deployment strategy | Serverpod - + diff --git a/docs/1.1.0/deployments/general.html b/docs/1.1.0/deployments/general.html index 6aad148be..98e48ad07 100644 --- a/docs/1.1.0/deployments/general.html +++ b/docs/1.1.0/deployments/general.html @@ -4,7 +4,7 @@ Hosting elsewhere | Serverpod - + diff --git a/docs/1.1.0/insights.html b/docs/1.1.0/insights.html index a4a2f8314..d5b440ee8 100644 --- a/docs/1.1.0/insights.html +++ b/docs/1.1.0/insights.html @@ -4,7 +4,7 @@ Serverpod Insights | Serverpod - + diff --git a/docs/1.1.0/roadmap.html b/docs/1.1.0/roadmap.html index cf887d2fc..743b9e28b 100644 --- a/docs/1.1.0/roadmap.html +++ b/docs/1.1.0/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/1.1.0/support.html b/docs/1.1.0/support.html index 7bce1029f..6343a4675 100644 --- a/docs/1.1.0/support.html +++ b/docs/1.1.0/support.html @@ -4,7 +4,7 @@ Support & community | Serverpod - + diff --git a/docs/1.1.0/tutorials.html b/docs/1.1.0/tutorials.html index 0acd8d6ad..cb7e573e9 100644 --- a/docs/1.1.0/tutorials.html +++ b/docs/1.1.0/tutorials.html @@ -4,7 +4,7 @@ Tutorials & Examples | Serverpod - + diff --git a/docs/1.1.1.html b/docs/1.1.1.html index f1151798f..07bfd8c8e 100644 --- a/docs/1.1.1.html +++ b/docs/1.1.1.html @@ -4,7 +4,7 @@ Installing Serverpod | Serverpod - + diff --git a/docs/1.1.1/capabilities.html b/docs/1.1.1/capabilities.html index 0535b2e9d..d016228a5 100644 --- a/docs/1.1.1/capabilities.html +++ b/docs/1.1.1/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/1.1.1/concepts/authentication/basics.html b/docs/1.1.1/concepts/authentication/basics.html index 2e15e919d..f12a17223 100644 --- a/docs/1.1.1/concepts/authentication/basics.html +++ b/docs/1.1.1/concepts/authentication/basics.html @@ -4,7 +4,7 @@ The basics | Serverpod - + diff --git a/docs/1.1.1/concepts/authentication/providers/apple.html b/docs/1.1.1/concepts/authentication/providers/apple.html index f79971d47..d14cf2235 100644 --- a/docs/1.1.1/concepts/authentication/providers/apple.html +++ b/docs/1.1.1/concepts/authentication/providers/apple.html @@ -4,7 +4,7 @@ Apple | Serverpod - + diff --git a/docs/1.1.1/concepts/authentication/providers/email.html b/docs/1.1.1/concepts/authentication/providers/email.html index f8b5b7628..129218261 100644 --- a/docs/1.1.1/concepts/authentication/providers/email.html +++ b/docs/1.1.1/concepts/authentication/providers/email.html @@ -4,7 +4,7 @@ Email | Serverpod - + diff --git a/docs/1.1.1/concepts/authentication/providers/firebase.html b/docs/1.1.1/concepts/authentication/providers/firebase.html index c2715fdb8..8acdc6545 100644 --- a/docs/1.1.1/concepts/authentication/providers/firebase.html +++ b/docs/1.1.1/concepts/authentication/providers/firebase.html @@ -4,7 +4,7 @@ Firebase | Serverpod - + diff --git a/docs/1.1.1/concepts/authentication/providers/google.html b/docs/1.1.1/concepts/authentication/providers/google.html index 0d8869c45..8e8407fe4 100644 --- a/docs/1.1.1/concepts/authentication/providers/google.html +++ b/docs/1.1.1/concepts/authentication/providers/google.html @@ -4,7 +4,7 @@ Google | Serverpod - + diff --git a/docs/1.1.1/concepts/authentication/setup.html b/docs/1.1.1/concepts/authentication/setup.html index a7d9b607c..80f1de509 100644 --- a/docs/1.1.1/concepts/authentication/setup.html +++ b/docs/1.1.1/concepts/authentication/setup.html @@ -4,7 +4,7 @@ Setup | Serverpod - + diff --git a/docs/1.1.1/concepts/authentication/working-with-users.html b/docs/1.1.1/concepts/authentication/working-with-users.html index 3bd822fd2..f258d19eb 100644 --- a/docs/1.1.1/concepts/authentication/working-with-users.html +++ b/docs/1.1.1/concepts/authentication/working-with-users.html @@ -4,7 +4,7 @@ Working with users | Serverpod - + diff --git a/docs/1.1.1/concepts/backward-compatibility.html b/docs/1.1.1/concepts/backward-compatibility.html index 7418efe69..e8d714105 100644 --- a/docs/1.1.1/concepts/backward-compatibility.html +++ b/docs/1.1.1/concepts/backward-compatibility.html @@ -4,7 +4,7 @@ Backward compatibility | Serverpod - + diff --git a/docs/1.1.1/concepts/caching.html b/docs/1.1.1/concepts/caching.html index c702aa68e..a5e925fc9 100644 --- a/docs/1.1.1/concepts/caching.html +++ b/docs/1.1.1/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/1.1.1/concepts/database-communication.html b/docs/1.1.1/concepts/database-communication.html index 45911fbd6..16fb33f01 100644 --- a/docs/1.1.1/concepts/database-communication.html +++ b/docs/1.1.1/concepts/database-communication.html @@ -4,7 +4,7 @@ Database communication | Serverpod - + diff --git a/docs/1.1.1/concepts/exceptions.html b/docs/1.1.1/concepts/exceptions.html index 57a9fcdd5..2c99c9750 100644 --- a/docs/1.1.1/concepts/exceptions.html +++ b/docs/1.1.1/concepts/exceptions.html @@ -4,7 +4,7 @@ Error handling and exceptions | Serverpod - + diff --git a/docs/1.1.1/concepts/file-uploads.html b/docs/1.1.1/concepts/file-uploads.html index 50f220f2c..b04cb8992 100644 --- a/docs/1.1.1/concepts/file-uploads.html +++ b/docs/1.1.1/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/1.1.1/concepts/health-checks.html b/docs/1.1.1/concepts/health-checks.html index bfc51132a..e1da002d3 100644 --- a/docs/1.1.1/concepts/health-checks.html +++ b/docs/1.1.1/concepts/health-checks.html @@ -4,7 +4,7 @@ Health checks | Serverpod - + diff --git a/docs/1.1.1/concepts/logging.html b/docs/1.1.1/concepts/logging.html index e32dd1e09..91dde58b4 100644 --- a/docs/1.1.1/concepts/logging.html +++ b/docs/1.1.1/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/1.1.1/concepts/modules.html b/docs/1.1.1/concepts/modules.html index dbb6831ba..28cdb134c 100644 --- a/docs/1.1.1/concepts/modules.html +++ b/docs/1.1.1/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/1.1.1/concepts/serialization.html b/docs/1.1.1/concepts/serialization.html index 72dafaf53..d68c62193 100644 --- a/docs/1.1.1/concepts/serialization.html +++ b/docs/1.1.1/concepts/serialization.html @@ -4,7 +4,7 @@ Serialization | Serverpod - + diff --git a/docs/1.1.1/concepts/sessions.html b/docs/1.1.1/concepts/sessions.html index b6c47c3e0..b23003d99 100644 --- a/docs/1.1.1/concepts/sessions.html +++ b/docs/1.1.1/concepts/sessions.html @@ -4,7 +4,7 @@ Sessions | Serverpod - + diff --git a/docs/1.1.1/concepts/streams.html b/docs/1.1.1/concepts/streams.html index 05692cc1f..af8e6d767 100644 --- a/docs/1.1.1/concepts/streams.html +++ b/docs/1.1.1/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/1.1.1/concepts/webserver.html b/docs/1.1.1/concepts/webserver.html index 85b3b04c3..d984e338d 100644 --- a/docs/1.1.1/concepts/webserver.html +++ b/docs/1.1.1/concepts/webserver.html @@ -4,7 +4,7 @@ Web server | Serverpod - + diff --git a/docs/1.1.1/concepts/working-with-endpoints.html b/docs/1.1.1/concepts/working-with-endpoints.html index 66e2baa9f..45e2eab29 100644 --- a/docs/1.1.1/concepts/working-with-endpoints.html +++ b/docs/1.1.1/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/1.1.1/contribute.html b/docs/1.1.1/contribute.html index bd7e4a44e..a424b3774 100644 --- a/docs/1.1.1/contribute.html +++ b/docs/1.1.1/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/1.1.1/deployments/deploying-to-aws.html b/docs/1.1.1/deployments/deploying-to-aws.html index 17b0a9284..dbf8090bc 100644 --- a/docs/1.1.1/deployments/deploying-to-aws.html +++ b/docs/1.1.1/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ AWS EC2 with Terraform | Serverpod - + diff --git a/docs/1.1.1/deployments/deploying-to-gce-terraform.html b/docs/1.1.1/deployments/deploying-to-gce-terraform.html index 6105aa052..69869a057 100644 --- a/docs/1.1.1/deployments/deploying-to-gce-terraform.html +++ b/docs/1.1.1/deployments/deploying-to-gce-terraform.html @@ -4,7 +4,7 @@ Google Cloud Engine with Terraform | Serverpod - + diff --git a/docs/1.1.1/deployments/deploying-to-gcr-console.html b/docs/1.1.1/deployments/deploying-to-gcr-console.html index 00df15922..df2a5fef3 100644 --- a/docs/1.1.1/deployments/deploying-to-gcr-console.html +++ b/docs/1.1.1/deployments/deploying-to-gcr-console.html @@ -4,7 +4,7 @@ Google Cloud Run with CGP Console | Serverpod - + diff --git a/docs/1.1.1/deployments/deployment-strategy.html b/docs/1.1.1/deployments/deployment-strategy.html index 1be2b98b6..c47d259bb 100644 --- a/docs/1.1.1/deployments/deployment-strategy.html +++ b/docs/1.1.1/deployments/deployment-strategy.html @@ -4,7 +4,7 @@ Choosing deployment strategy | Serverpod - + diff --git a/docs/1.1.1/deployments/general.html b/docs/1.1.1/deployments/general.html index 7d5ea7311..d751acc15 100644 --- a/docs/1.1.1/deployments/general.html +++ b/docs/1.1.1/deployments/general.html @@ -4,7 +4,7 @@ Hosting elsewhere | Serverpod - + diff --git a/docs/1.1.1/get-started.html b/docs/1.1.1/get-started.html index 81fec6d48..279cc3f86 100644 --- a/docs/1.1.1/get-started.html +++ b/docs/1.1.1/get-started.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/1.1.1/insights.html b/docs/1.1.1/insights.html index 12ce3f3d5..f90253a44 100644 --- a/docs/1.1.1/insights.html +++ b/docs/1.1.1/insights.html @@ -4,7 +4,7 @@ Serverpod Insights | Serverpod - + diff --git a/docs/1.1.1/roadmap.html b/docs/1.1.1/roadmap.html index 00133e339..d3b9f2509 100644 --- a/docs/1.1.1/roadmap.html +++ b/docs/1.1.1/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/1.1.1/support.html b/docs/1.1.1/support.html index 70227957c..d80963618 100644 --- a/docs/1.1.1/support.html +++ b/docs/1.1.1/support.html @@ -4,7 +4,7 @@ Support & community | Serverpod - + diff --git a/docs/1.1.1/tutorials/authentication.html b/docs/1.1.1/tutorials/authentication.html index 22a93fac2..6f228ac99 100644 --- a/docs/1.1.1/tutorials/authentication.html +++ b/docs/1.1.1/tutorials/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/1.1.1/tutorials/code-example.html b/docs/1.1.1/tutorials/code-example.html index a23d9b4d3..d2c422114 100644 --- a/docs/1.1.1/tutorials/code-example.html +++ b/docs/1.1.1/tutorials/code-example.html @@ -4,7 +4,7 @@ Code examples | Serverpod - + diff --git a/docs/1.1.1/tutorials/first-app.html b/docs/1.1.1/tutorials/first-app.html index 36f10f10f..d35216d02 100644 --- a/docs/1.1.1/tutorials/first-app.html +++ b/docs/1.1.1/tutorials/first-app.html @@ -4,7 +4,7 @@ Build your first app | Serverpod - + diff --git a/docs/1.1.1/tutorials/videos.html b/docs/1.1.1/tutorials/videos.html index e55a614e6..f4b0fddb4 100644 --- a/docs/1.1.1/tutorials/videos.html +++ b/docs/1.1.1/tutorials/videos.html @@ -4,7 +4,7 @@ Videos | Serverpod - + diff --git a/docs/1.2.0.html b/docs/1.2.0.html index 3cdc63065..12d59b0a6 100644 --- a/docs/1.2.0.html +++ b/docs/1.2.0.html @@ -4,7 +4,7 @@ Installing Serverpod | Serverpod - + diff --git a/docs/1.2.0/capabilities.html b/docs/1.2.0/capabilities.html index 2febbb898..0553b5bad 100644 --- a/docs/1.2.0/capabilities.html +++ b/docs/1.2.0/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/1.2.0/cli.html b/docs/1.2.0/cli.html index 26b283ff1..d43a338b8 100644 --- a/docs/1.2.0/cli.html +++ b/docs/1.2.0/cli.html @@ -4,7 +4,7 @@ Serverpod CLI | Serverpod - + diff --git a/docs/1.2.0/concepts/authentication/basics.html b/docs/1.2.0/concepts/authentication/basics.html index f307e1e5a..5c275fcea 100644 --- a/docs/1.2.0/concepts/authentication/basics.html +++ b/docs/1.2.0/concepts/authentication/basics.html @@ -4,7 +4,7 @@ The basics | Serverpod - + diff --git a/docs/1.2.0/concepts/authentication/custom-overrides.html b/docs/1.2.0/concepts/authentication/custom-overrides.html index 69de2e99b..43f9296ba 100644 --- a/docs/1.2.0/concepts/authentication/custom-overrides.html +++ b/docs/1.2.0/concepts/authentication/custom-overrides.html @@ -4,7 +4,7 @@ Custom overrides | Serverpod - + diff --git a/docs/1.2.0/concepts/authentication/providers/apple.html b/docs/1.2.0/concepts/authentication/providers/apple.html index de3587226..03b377af4 100644 --- a/docs/1.2.0/concepts/authentication/providers/apple.html +++ b/docs/1.2.0/concepts/authentication/providers/apple.html @@ -4,7 +4,7 @@ Apple | Serverpod - + diff --git a/docs/1.2.0/concepts/authentication/providers/custom-providers.html b/docs/1.2.0/concepts/authentication/providers/custom-providers.html index 2463e27c0..d2d144a78 100644 --- a/docs/1.2.0/concepts/authentication/providers/custom-providers.html +++ b/docs/1.2.0/concepts/authentication/providers/custom-providers.html @@ -4,7 +4,7 @@ Custom providers | Serverpod - + diff --git a/docs/1.2.0/concepts/authentication/providers/email.html b/docs/1.2.0/concepts/authentication/providers/email.html index 7b6bca33b..863632a48 100644 --- a/docs/1.2.0/concepts/authentication/providers/email.html +++ b/docs/1.2.0/concepts/authentication/providers/email.html @@ -4,7 +4,7 @@ Email | Serverpod - + diff --git a/docs/1.2.0/concepts/authentication/providers/firebase.html b/docs/1.2.0/concepts/authentication/providers/firebase.html index b5701318a..9044262b1 100644 --- a/docs/1.2.0/concepts/authentication/providers/firebase.html +++ b/docs/1.2.0/concepts/authentication/providers/firebase.html @@ -4,7 +4,7 @@ Firebase | Serverpod - + diff --git a/docs/1.2.0/concepts/authentication/providers/google.html b/docs/1.2.0/concepts/authentication/providers/google.html index a618fcebe..0c3f92630 100644 --- a/docs/1.2.0/concepts/authentication/providers/google.html +++ b/docs/1.2.0/concepts/authentication/providers/google.html @@ -4,7 +4,7 @@ Google | Serverpod - + diff --git a/docs/1.2.0/concepts/authentication/setup.html b/docs/1.2.0/concepts/authentication/setup.html index 9a37a22ea..32679ba68 100644 --- a/docs/1.2.0/concepts/authentication/setup.html +++ b/docs/1.2.0/concepts/authentication/setup.html @@ -4,7 +4,7 @@ Setup | Serverpod - + diff --git a/docs/1.2.0/concepts/authentication/working-with-users.html b/docs/1.2.0/concepts/authentication/working-with-users.html index 7daa79923..12734e0ac 100644 --- a/docs/1.2.0/concepts/authentication/working-with-users.html +++ b/docs/1.2.0/concepts/authentication/working-with-users.html @@ -4,7 +4,7 @@ Working with users | Serverpod - + diff --git a/docs/1.2.0/concepts/backward-compatibility.html b/docs/1.2.0/concepts/backward-compatibility.html index 05307bf2d..4dcd4ba17 100644 --- a/docs/1.2.0/concepts/backward-compatibility.html +++ b/docs/1.2.0/concepts/backward-compatibility.html @@ -4,7 +4,7 @@ Backward compatibility | Serverpod - + diff --git a/docs/1.2.0/concepts/caching.html b/docs/1.2.0/concepts/caching.html index dee78e248..b003d4738 100644 --- a/docs/1.2.0/concepts/caching.html +++ b/docs/1.2.0/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/1.2.0/concepts/database/connection.html b/docs/1.2.0/concepts/database/connection.html index d52f6979e..c16b1873a 100644 --- a/docs/1.2.0/concepts/database/connection.html +++ b/docs/1.2.0/concepts/database/connection.html @@ -4,7 +4,7 @@ Connection | Serverpod - + diff --git a/docs/1.2.0/concepts/database/crud.html b/docs/1.2.0/concepts/database/crud.html index 7359b2894..55ece5bbc 100644 --- a/docs/1.2.0/concepts/database/crud.html +++ b/docs/1.2.0/concepts/database/crud.html @@ -4,7 +4,7 @@ CRUD | Serverpod - + diff --git a/docs/1.2.0/concepts/database/filter.html b/docs/1.2.0/concepts/database/filter.html index e624c6845..29a047077 100644 --- a/docs/1.2.0/concepts/database/filter.html +++ b/docs/1.2.0/concepts/database/filter.html @@ -4,7 +4,7 @@ Filter | Serverpod - + diff --git a/docs/1.2.0/concepts/database/indexing.html b/docs/1.2.0/concepts/database/indexing.html index 18c3eb148..96481b46c 100644 --- a/docs/1.2.0/concepts/database/indexing.html +++ b/docs/1.2.0/concepts/database/indexing.html @@ -4,7 +4,7 @@ Indexing | Serverpod - + diff --git a/docs/1.2.0/concepts/database/migrations.html b/docs/1.2.0/concepts/database/migrations.html index c4589687d..28ac81513 100644 --- a/docs/1.2.0/concepts/database/migrations.html +++ b/docs/1.2.0/concepts/database/migrations.html @@ -4,7 +4,7 @@ Migrations | Serverpod - + diff --git a/docs/1.2.0/concepts/database/models.html b/docs/1.2.0/concepts/database/models.html index 2a366df1b..90f32d66d 100644 --- a/docs/1.2.0/concepts/database/models.html +++ b/docs/1.2.0/concepts/database/models.html @@ -4,7 +4,7 @@ Models | Serverpod - + diff --git a/docs/1.2.0/concepts/database/pagination.html b/docs/1.2.0/concepts/database/pagination.html index 0034b4510..5d707c281 100644 --- a/docs/1.2.0/concepts/database/pagination.html +++ b/docs/1.2.0/concepts/database/pagination.html @@ -4,7 +4,7 @@ Pagination | Serverpod - + diff --git a/docs/1.2.0/concepts/database/raw-access.html b/docs/1.2.0/concepts/database/raw-access.html index 3d13fb2f3..5f7ad66fd 100644 --- a/docs/1.2.0/concepts/database/raw-access.html +++ b/docs/1.2.0/concepts/database/raw-access.html @@ -4,7 +4,7 @@ Raw access | Serverpod - + diff --git a/docs/1.2.0/concepts/database/relation-queries.html b/docs/1.2.0/concepts/database/relation-queries.html index 131217c3c..c5ff97c1c 100644 --- a/docs/1.2.0/concepts/database/relation-queries.html +++ b/docs/1.2.0/concepts/database/relation-queries.html @@ -4,7 +4,7 @@ Relation queries | Serverpod - + diff --git a/docs/1.2.0/concepts/database/relations/many-to-many.html b/docs/1.2.0/concepts/database/relations/many-to-many.html index 3422288d7..f8834216b 100644 --- a/docs/1.2.0/concepts/database/relations/many-to-many.html +++ b/docs/1.2.0/concepts/database/relations/many-to-many.html @@ -4,7 +4,7 @@ Many-to-Many | Serverpod - + diff --git a/docs/1.2.0/concepts/database/relations/modules.html b/docs/1.2.0/concepts/database/relations/modules.html index 176d598dc..b4abd7787 100644 --- a/docs/1.2.0/concepts/database/relations/modules.html +++ b/docs/1.2.0/concepts/database/relations/modules.html @@ -4,7 +4,7 @@ Relations with modules | Serverpod - + diff --git a/docs/1.2.0/concepts/database/relations/one-to-many.html b/docs/1.2.0/concepts/database/relations/one-to-many.html index 6ae6006eb..fbdb03f24 100644 --- a/docs/1.2.0/concepts/database/relations/one-to-many.html +++ b/docs/1.2.0/concepts/database/relations/one-to-many.html @@ -4,7 +4,7 @@ One-to-many | Serverpod - + diff --git a/docs/1.2.0/concepts/database/relations/one-to-one.html b/docs/1.2.0/concepts/database/relations/one-to-one.html index a8ae0d098..93f030fd4 100644 --- a/docs/1.2.0/concepts/database/relations/one-to-one.html +++ b/docs/1.2.0/concepts/database/relations/one-to-one.html @@ -4,7 +4,7 @@ One-to-one | Serverpod - + diff --git a/docs/1.2.0/concepts/database/relations/referential-actions.html b/docs/1.2.0/concepts/database/relations/referential-actions.html index 71a4045b6..14744390d 100644 --- a/docs/1.2.0/concepts/database/relations/referential-actions.html +++ b/docs/1.2.0/concepts/database/relations/referential-actions.html @@ -4,7 +4,7 @@ Referential actions | Serverpod - + diff --git a/docs/1.2.0/concepts/database/relations/self-relations.html b/docs/1.2.0/concepts/database/relations/self-relations.html index 59f22e82b..cfcc37731 100644 --- a/docs/1.2.0/concepts/database/relations/self-relations.html +++ b/docs/1.2.0/concepts/database/relations/self-relations.html @@ -4,7 +4,7 @@ Self-relations | Serverpod - + diff --git a/docs/1.2.0/concepts/database/sort.html b/docs/1.2.0/concepts/database/sort.html index 12559481f..c1acb9549 100644 --- a/docs/1.2.0/concepts/database/sort.html +++ b/docs/1.2.0/concepts/database/sort.html @@ -4,7 +4,7 @@ Sort | Serverpod - + diff --git a/docs/1.2.0/concepts/database/transactions.html b/docs/1.2.0/concepts/database/transactions.html index 56802d6df..710fbaf42 100644 --- a/docs/1.2.0/concepts/database/transactions.html +++ b/docs/1.2.0/concepts/database/transactions.html @@ -4,7 +4,7 @@ Transactions | Serverpod - + diff --git a/docs/1.2.0/concepts/exceptions.html b/docs/1.2.0/concepts/exceptions.html index 4903640de..77c952682 100644 --- a/docs/1.2.0/concepts/exceptions.html +++ b/docs/1.2.0/concepts/exceptions.html @@ -4,7 +4,7 @@ Error handling and exceptions | Serverpod - + diff --git a/docs/1.2.0/concepts/file-uploads.html b/docs/1.2.0/concepts/file-uploads.html index ce5080678..4b2cc8ffa 100644 --- a/docs/1.2.0/concepts/file-uploads.html +++ b/docs/1.2.0/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/1.2.0/concepts/health-checks.html b/docs/1.2.0/concepts/health-checks.html index d0973d4bb..02c5650be 100644 --- a/docs/1.2.0/concepts/health-checks.html +++ b/docs/1.2.0/concepts/health-checks.html @@ -4,7 +4,7 @@ Health checks | Serverpod - + diff --git a/docs/1.2.0/concepts/logging.html b/docs/1.2.0/concepts/logging.html index d09ac1776..4761d9271 100644 --- a/docs/1.2.0/concepts/logging.html +++ b/docs/1.2.0/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/1.2.0/concepts/models.html b/docs/1.2.0/concepts/models.html index df3d7b5bd..726fc4592 100644 --- a/docs/1.2.0/concepts/models.html +++ b/docs/1.2.0/concepts/models.html @@ -4,7 +4,7 @@ Working with models | Serverpod - + @@ -31,7 +31,7 @@

EnumBy default the serialization will convert the enum to an int representing the index of the value. Changing the order may therefore have unforeseen consequences when reusing old data (such as from a database). Changing the serialization to be based on the name instead of index is easy.

enum: Animal
serialized: byName
values:
- dog
- cat
- bird

serialized has two valid values byName and byIndex. When using byName the string literal of the enum is used, when using byIndex the index value (0, 1, 2, etc) is used.

-
info

It's recommended to always set serialized to byName in any new Enum models, as this is less fragile and will be changed to the default setting in version 2 of Serverpod.

+
info

It's recommended to always set serialized to byName in any new Enum models, as this is less fragile and will be changed to the default setting in version 3 of Serverpod.

Adding documentation

Serverpod allows you to add documentation to your serializable objects in a similar way that you would add documentation to your Dart code. Use three hashes (###) to indicate that a comment should be considered documentation.

### Information about a company.
class: Company
fields:
### The name of the company.
name: String

### The date the company was founded, if known.
foundedDate: DateTime?

### A list of people currently employed at the company.
employees: List<Employee>
diff --git a/docs/1.2.0/concepts/modules.html b/docs/1.2.0/concepts/modules.html index 540682b1d..14d56afb0 100644 --- a/docs/1.2.0/concepts/modules.html +++ b/docs/1.2.0/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/1.2.0/concepts/scheduling.html b/docs/1.2.0/concepts/scheduling.html index d46c8d606..da43fd22d 100644 --- a/docs/1.2.0/concepts/scheduling.html +++ b/docs/1.2.0/concepts/scheduling.html @@ -4,7 +4,7 @@ Scheduling | Serverpod - + diff --git a/docs/1.2.0/concepts/serialization.html b/docs/1.2.0/concepts/serialization.html index 22857282e..5ad3d6a01 100644 --- a/docs/1.2.0/concepts/serialization.html +++ b/docs/1.2.0/concepts/serialization.html @@ -4,7 +4,7 @@ Custom serialization | Serverpod - + diff --git a/docs/1.2.0/concepts/sessions.html b/docs/1.2.0/concepts/sessions.html index 923bfc118..ac8c50e25 100644 --- a/docs/1.2.0/concepts/sessions.html +++ b/docs/1.2.0/concepts/sessions.html @@ -4,7 +4,7 @@ Sessions | Serverpod - + diff --git a/docs/1.2.0/concepts/streams.html b/docs/1.2.0/concepts/streams.html index ea7bcdc70..9bc2c8edd 100644 --- a/docs/1.2.0/concepts/streams.html +++ b/docs/1.2.0/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/1.2.0/concepts/webserver.html b/docs/1.2.0/concepts/webserver.html index cf6d4ef87..bb270f29e 100644 --- a/docs/1.2.0/concepts/webserver.html +++ b/docs/1.2.0/concepts/webserver.html @@ -4,7 +4,7 @@ Web server | Serverpod - + diff --git a/docs/1.2.0/concepts/working-with-endpoints.html b/docs/1.2.0/concepts/working-with-endpoints.html index 887df3a3f..bd15489be 100644 --- a/docs/1.2.0/concepts/working-with-endpoints.html +++ b/docs/1.2.0/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/1.2.0/contribute.html b/docs/1.2.0/contribute.html index 60343aeff..3c6cb7fc3 100644 --- a/docs/1.2.0/contribute.html +++ b/docs/1.2.0/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/1.2.0/deployments/deploying-to-aws.html b/docs/1.2.0/deployments/deploying-to-aws.html index f78acb0a7..37ef4c3c8 100644 --- a/docs/1.2.0/deployments/deploying-to-aws.html +++ b/docs/1.2.0/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ AWS EC2 with Terraform | Serverpod - + diff --git a/docs/1.2.0/deployments/deploying-to-gce-terraform.html b/docs/1.2.0/deployments/deploying-to-gce-terraform.html index 15e792d0b..964019cad 100644 --- a/docs/1.2.0/deployments/deploying-to-gce-terraform.html +++ b/docs/1.2.0/deployments/deploying-to-gce-terraform.html @@ -4,7 +4,7 @@ Google Cloud Engine with Terraform | Serverpod - + diff --git a/docs/1.2.0/deployments/deploying-to-gcr-console.html b/docs/1.2.0/deployments/deploying-to-gcr-console.html index a5a09caac..c1013e303 100644 --- a/docs/1.2.0/deployments/deploying-to-gcr-console.html +++ b/docs/1.2.0/deployments/deploying-to-gcr-console.html @@ -4,7 +4,7 @@ Google Cloud Run with CGP Console | Serverpod - + diff --git a/docs/1.2.0/deployments/deployment-strategy.html b/docs/1.2.0/deployments/deployment-strategy.html index aaf543f43..8a19b29d8 100644 --- a/docs/1.2.0/deployments/deployment-strategy.html +++ b/docs/1.2.0/deployments/deployment-strategy.html @@ -4,7 +4,7 @@ Choosing deployment strategy | Serverpod - + diff --git a/docs/1.2.0/deployments/general.html b/docs/1.2.0/deployments/general.html index ca4249321..6c01e006d 100644 --- a/docs/1.2.0/deployments/general.html +++ b/docs/1.2.0/deployments/general.html @@ -4,7 +4,7 @@ Hosting elsewhere | Serverpod - + diff --git a/docs/1.2.0/get-started.html b/docs/1.2.0/get-started.html index 43590f36e..3980ddd91 100644 --- a/docs/1.2.0/get-started.html +++ b/docs/1.2.0/get-started.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/1.2.0/insights.html b/docs/1.2.0/insights.html index 73e551e05..af48507a2 100644 --- a/docs/1.2.0/insights.html +++ b/docs/1.2.0/insights.html @@ -4,7 +4,7 @@ Serverpod Insights | Serverpod - + diff --git a/docs/1.2.0/lsp.html b/docs/1.2.0/lsp.html index 9564a0150..683fb2c2a 100644 --- a/docs/1.2.0/lsp.html +++ b/docs/1.2.0/lsp.html @@ -4,7 +4,7 @@ Serverpod LSP | Serverpod - + diff --git a/docs/1.2.0/roadmap.html b/docs/1.2.0/roadmap.html index 2a45d9ada..37714672b 100644 --- a/docs/1.2.0/roadmap.html +++ b/docs/1.2.0/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/1.2.0/support.html b/docs/1.2.0/support.html index 7871f6eb5..8fef1d40b 100644 --- a/docs/1.2.0/support.html +++ b/docs/1.2.0/support.html @@ -4,7 +4,7 @@ Support & community | Serverpod - + diff --git a/docs/1.2.0/tutorials/authentication.html b/docs/1.2.0/tutorials/authentication.html index 8372251bf..7233f5c08 100644 --- a/docs/1.2.0/tutorials/authentication.html +++ b/docs/1.2.0/tutorials/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/1.2.0/tutorials/code-example.html b/docs/1.2.0/tutorials/code-example.html index a8d7c9bb4..4e8253951 100644 --- a/docs/1.2.0/tutorials/code-example.html +++ b/docs/1.2.0/tutorials/code-example.html @@ -4,7 +4,7 @@ Code examples | Serverpod - + diff --git a/docs/1.2.0/tutorials/first-app.html b/docs/1.2.0/tutorials/first-app.html index b596270fd..cce90d2a1 100644 --- a/docs/1.2.0/tutorials/first-app.html +++ b/docs/1.2.0/tutorials/first-app.html @@ -4,7 +4,7 @@ Build your first app | Serverpod - + diff --git a/docs/1.2.0/tutorials/videos.html b/docs/1.2.0/tutorials/videos.html index 42433e6a6..b519b9587 100644 --- a/docs/1.2.0/tutorials/videos.html +++ b/docs/1.2.0/tutorials/videos.html @@ -4,7 +4,7 @@ Videos | Serverpod - + diff --git a/docs/1.2.0/upgrading/upgrade-to-one-point-two.html b/docs/1.2.0/upgrading/upgrade-to-one-point-two.html index 2aa49c710..7714b11d2 100644 --- a/docs/1.2.0/upgrading/upgrade-to-one-point-two.html +++ b/docs/1.2.0/upgrading/upgrade-to-one-point-two.html @@ -4,7 +4,7 @@ Upgrade to 1.2 | Serverpod - + diff --git a/docs/2.0.0.html b/docs/2.0.0.html index 5afefc6d9..835b2974a 100644 --- a/docs/2.0.0.html +++ b/docs/2.0.0.html @@ -4,7 +4,7 @@ Installing Serverpod | Serverpod - + diff --git a/docs/2.0.0/capabilities.html b/docs/2.0.0/capabilities.html index 1fa0865d0..62b75b1eb 100644 --- a/docs/2.0.0/capabilities.html +++ b/docs/2.0.0/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/2.0.0/concepts/authentication/basics.html b/docs/2.0.0/concepts/authentication/basics.html index 698c41541..6c9898c89 100644 --- a/docs/2.0.0/concepts/authentication/basics.html +++ b/docs/2.0.0/concepts/authentication/basics.html @@ -4,7 +4,7 @@ The basics | Serverpod - + diff --git a/docs/2.0.0/concepts/authentication/custom-overrides.html b/docs/2.0.0/concepts/authentication/custom-overrides.html index 570b585ec..7922b0460 100644 --- a/docs/2.0.0/concepts/authentication/custom-overrides.html +++ b/docs/2.0.0/concepts/authentication/custom-overrides.html @@ -4,7 +4,7 @@ Custom overrides | Serverpod - + diff --git a/docs/2.0.0/concepts/authentication/providers/apple.html b/docs/2.0.0/concepts/authentication/providers/apple.html index 229e85eb8..b5037e782 100644 --- a/docs/2.0.0/concepts/authentication/providers/apple.html +++ b/docs/2.0.0/concepts/authentication/providers/apple.html @@ -4,7 +4,7 @@ Apple | Serverpod - + diff --git a/docs/2.0.0/concepts/authentication/providers/custom-providers.html b/docs/2.0.0/concepts/authentication/providers/custom-providers.html index 4bee7de9f..79c801d28 100644 --- a/docs/2.0.0/concepts/authentication/providers/custom-providers.html +++ b/docs/2.0.0/concepts/authentication/providers/custom-providers.html @@ -4,7 +4,7 @@ Custom providers | Serverpod - + diff --git a/docs/2.0.0/concepts/authentication/providers/email.html b/docs/2.0.0/concepts/authentication/providers/email.html index 0c2ca2e31..124078fcb 100644 --- a/docs/2.0.0/concepts/authentication/providers/email.html +++ b/docs/2.0.0/concepts/authentication/providers/email.html @@ -4,7 +4,7 @@ Email | Serverpod - + diff --git a/docs/2.0.0/concepts/authentication/providers/firebase.html b/docs/2.0.0/concepts/authentication/providers/firebase.html index 5a192f930..5773191c2 100644 --- a/docs/2.0.0/concepts/authentication/providers/firebase.html +++ b/docs/2.0.0/concepts/authentication/providers/firebase.html @@ -4,7 +4,7 @@ Firebase | Serverpod - + diff --git a/docs/2.0.0/concepts/authentication/providers/google.html b/docs/2.0.0/concepts/authentication/providers/google.html index f05732cdf..f64f656c9 100644 --- a/docs/2.0.0/concepts/authentication/providers/google.html +++ b/docs/2.0.0/concepts/authentication/providers/google.html @@ -4,7 +4,7 @@ Google | Serverpod - + diff --git a/docs/2.0.0/concepts/authentication/setup.html b/docs/2.0.0/concepts/authentication/setup.html index fa7c14e03..0c356727a 100644 --- a/docs/2.0.0/concepts/authentication/setup.html +++ b/docs/2.0.0/concepts/authentication/setup.html @@ -4,7 +4,7 @@ Setup | Serverpod - + diff --git a/docs/2.0.0/concepts/authentication/working-with-users.html b/docs/2.0.0/concepts/authentication/working-with-users.html index 644fb6f8c..a34ffb4f0 100644 --- a/docs/2.0.0/concepts/authentication/working-with-users.html +++ b/docs/2.0.0/concepts/authentication/working-with-users.html @@ -4,7 +4,7 @@ Working with users | Serverpod - + diff --git a/docs/2.0.0/concepts/backward-compatibility.html b/docs/2.0.0/concepts/backward-compatibility.html index 7262b4240..d09b54792 100644 --- a/docs/2.0.0/concepts/backward-compatibility.html +++ b/docs/2.0.0/concepts/backward-compatibility.html @@ -4,7 +4,7 @@ Backward compatibility | Serverpod - + diff --git a/docs/2.0.0/concepts/caching.html b/docs/2.0.0/concepts/caching.html index b565d3c06..57b8c941e 100644 --- a/docs/2.0.0/concepts/caching.html +++ b/docs/2.0.0/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/2.0.0/concepts/database/connection.html b/docs/2.0.0/concepts/database/connection.html index d17c783b2..e44f6622d 100644 --- a/docs/2.0.0/concepts/database/connection.html +++ b/docs/2.0.0/concepts/database/connection.html @@ -4,7 +4,7 @@ Connection | Serverpod - + diff --git a/docs/2.0.0/concepts/database/crud.html b/docs/2.0.0/concepts/database/crud.html index fe4fd8efc..5e5c40984 100644 --- a/docs/2.0.0/concepts/database/crud.html +++ b/docs/2.0.0/concepts/database/crud.html @@ -4,7 +4,7 @@ CRUD | Serverpod - + diff --git a/docs/2.0.0/concepts/database/filter.html b/docs/2.0.0/concepts/database/filter.html index a515a3aab..5be2f46ba 100644 --- a/docs/2.0.0/concepts/database/filter.html +++ b/docs/2.0.0/concepts/database/filter.html @@ -4,7 +4,7 @@ Filter | Serverpod - + diff --git a/docs/2.0.0/concepts/database/indexing.html b/docs/2.0.0/concepts/database/indexing.html index bf68843aa..832ec65e0 100644 --- a/docs/2.0.0/concepts/database/indexing.html +++ b/docs/2.0.0/concepts/database/indexing.html @@ -4,7 +4,7 @@ Indexing | Serverpod - + diff --git a/docs/2.0.0/concepts/database/migrations.html b/docs/2.0.0/concepts/database/migrations.html index 27fd44c84..22bf54d0a 100644 --- a/docs/2.0.0/concepts/database/migrations.html +++ b/docs/2.0.0/concepts/database/migrations.html @@ -4,7 +4,7 @@ Migrations | Serverpod - + diff --git a/docs/2.0.0/concepts/database/models.html b/docs/2.0.0/concepts/database/models.html index deb953dfd..b6ce8951e 100644 --- a/docs/2.0.0/concepts/database/models.html +++ b/docs/2.0.0/concepts/database/models.html @@ -4,7 +4,7 @@ Models | Serverpod - + diff --git a/docs/2.0.0/concepts/database/pagination.html b/docs/2.0.0/concepts/database/pagination.html index a05c8835d..b3ffa1c60 100644 --- a/docs/2.0.0/concepts/database/pagination.html +++ b/docs/2.0.0/concepts/database/pagination.html @@ -4,7 +4,7 @@ Pagination | Serverpod - + diff --git a/docs/2.0.0/concepts/database/raw-access.html b/docs/2.0.0/concepts/database/raw-access.html index e1af824f1..0c34a9e96 100644 --- a/docs/2.0.0/concepts/database/raw-access.html +++ b/docs/2.0.0/concepts/database/raw-access.html @@ -4,7 +4,7 @@ Raw Access | Serverpod - + diff --git a/docs/2.0.0/concepts/database/relation-queries.html b/docs/2.0.0/concepts/database/relation-queries.html index 9984c9840..41f4d96ab 100644 --- a/docs/2.0.0/concepts/database/relation-queries.html +++ b/docs/2.0.0/concepts/database/relation-queries.html @@ -4,7 +4,7 @@ Relation queries | Serverpod - + diff --git a/docs/2.0.0/concepts/database/relations/many-to-many.html b/docs/2.0.0/concepts/database/relations/many-to-many.html index 019e3e4b9..66351934b 100644 --- a/docs/2.0.0/concepts/database/relations/many-to-many.html +++ b/docs/2.0.0/concepts/database/relations/many-to-many.html @@ -4,7 +4,7 @@ Many-to-Many | Serverpod - + diff --git a/docs/2.0.0/concepts/database/relations/modules.html b/docs/2.0.0/concepts/database/relations/modules.html index 38136458c..e516e33bb 100644 --- a/docs/2.0.0/concepts/database/relations/modules.html +++ b/docs/2.0.0/concepts/database/relations/modules.html @@ -4,7 +4,7 @@ Relations with modules | Serverpod - + diff --git a/docs/2.0.0/concepts/database/relations/one-to-many.html b/docs/2.0.0/concepts/database/relations/one-to-many.html index 6393ed580..6e7ebb1ff 100644 --- a/docs/2.0.0/concepts/database/relations/one-to-many.html +++ b/docs/2.0.0/concepts/database/relations/one-to-many.html @@ -4,7 +4,7 @@ One-to-many | Serverpod - + diff --git a/docs/2.0.0/concepts/database/relations/one-to-one.html b/docs/2.0.0/concepts/database/relations/one-to-one.html index cadb07bbe..b771cb457 100644 --- a/docs/2.0.0/concepts/database/relations/one-to-one.html +++ b/docs/2.0.0/concepts/database/relations/one-to-one.html @@ -4,7 +4,7 @@ One-to-one | Serverpod - + diff --git a/docs/2.0.0/concepts/database/relations/referential-actions.html b/docs/2.0.0/concepts/database/relations/referential-actions.html index 7555465ef..797f8a6aa 100644 --- a/docs/2.0.0/concepts/database/relations/referential-actions.html +++ b/docs/2.0.0/concepts/database/relations/referential-actions.html @@ -4,7 +4,7 @@ Referential actions | Serverpod - + diff --git a/docs/2.0.0/concepts/database/relations/self-relations.html b/docs/2.0.0/concepts/database/relations/self-relations.html index eac9c15fc..7ad0a6ded 100644 --- a/docs/2.0.0/concepts/database/relations/self-relations.html +++ b/docs/2.0.0/concepts/database/relations/self-relations.html @@ -4,7 +4,7 @@ Self-relations | Serverpod - + diff --git a/docs/2.0.0/concepts/database/sort.html b/docs/2.0.0/concepts/database/sort.html index d388f9b73..060b934ea 100644 --- a/docs/2.0.0/concepts/database/sort.html +++ b/docs/2.0.0/concepts/database/sort.html @@ -4,7 +4,7 @@ Sort | Serverpod - + diff --git a/docs/2.0.0/concepts/database/transactions.html b/docs/2.0.0/concepts/database/transactions.html index 89d048699..549cf10e4 100644 --- a/docs/2.0.0/concepts/database/transactions.html +++ b/docs/2.0.0/concepts/database/transactions.html @@ -4,7 +4,7 @@ Transactions | Serverpod - + diff --git a/docs/2.0.0/concepts/exceptions.html b/docs/2.0.0/concepts/exceptions.html index dd97741d9..04db720d7 100644 --- a/docs/2.0.0/concepts/exceptions.html +++ b/docs/2.0.0/concepts/exceptions.html @@ -4,7 +4,7 @@ Error handling and exceptions | Serverpod - + diff --git a/docs/2.0.0/concepts/file-uploads.html b/docs/2.0.0/concepts/file-uploads.html index 58ffbee64..283a19006 100644 --- a/docs/2.0.0/concepts/file-uploads.html +++ b/docs/2.0.0/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/2.0.0/concepts/health-checks.html b/docs/2.0.0/concepts/health-checks.html index 6f5e0af0a..bbc56fa0d 100644 --- a/docs/2.0.0/concepts/health-checks.html +++ b/docs/2.0.0/concepts/health-checks.html @@ -4,7 +4,7 @@ Health checks | Serverpod - + diff --git a/docs/2.0.0/concepts/logging.html b/docs/2.0.0/concepts/logging.html index 7204677d8..2cc50ce13 100644 --- a/docs/2.0.0/concepts/logging.html +++ b/docs/2.0.0/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/2.0.0/concepts/models.html b/docs/2.0.0/concepts/models.html index a88f88b5a..9c753d8cf 100644 --- a/docs/2.0.0/concepts/models.html +++ b/docs/2.0.0/concepts/models.html @@ -4,7 +4,7 @@ Working with models | Serverpod - + @@ -31,7 +31,7 @@

EnumBy default the serialization will convert the enum to an int representing the index of the value. Changing the order may therefore have unforeseen consequences when reusing old data (such as from a database). Changing the serialization to be based on the name instead of index is easy.

enum: Animal
serialized: byName
values:
- dog
- cat
- bird

serialized has two valid values byName and byIndex. When using byName the string literal of the enum is used, when using byIndex the index value (0, 1, 2, etc) is used.

-
info

It's recommended to always set serialized to byName in any new Enum models, as this is less fragile and will be changed to the default setting in version 2 of Serverpod.

+
info

It's recommended to always set serialized to byName in any new Enum models, as this is less fragile and will be changed to the default setting in version 3 of Serverpod.

Adding documentation

Serverpod allows you to add documentation to your serializable objects in a similar way that you would add documentation to your Dart code. Use three hashes (###) to indicate that a comment should be considered documentation.

### Information about a company.
class: Company
fields:
### The name of the company.
name: String

### The date the company was founded, if known.
foundedDate: DateTime?

### A list of people currently employed at the company.
employees: List<Employee>
diff --git a/docs/2.0.0/concepts/modules.html b/docs/2.0.0/concepts/modules.html index 61d57a211..5cbb32f48 100644 --- a/docs/2.0.0/concepts/modules.html +++ b/docs/2.0.0/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/2.0.0/concepts/scheduling.html b/docs/2.0.0/concepts/scheduling.html index 7f6d3e530..027da5049 100644 --- a/docs/2.0.0/concepts/scheduling.html +++ b/docs/2.0.0/concepts/scheduling.html @@ -4,7 +4,7 @@ Scheduling | Serverpod - + diff --git a/docs/2.0.0/concepts/serialization.html b/docs/2.0.0/concepts/serialization.html index 79ed84330..2d9497d48 100644 --- a/docs/2.0.0/concepts/serialization.html +++ b/docs/2.0.0/concepts/serialization.html @@ -4,7 +4,7 @@ Custom serialization | Serverpod - + diff --git a/docs/2.0.0/concepts/sessions.html b/docs/2.0.0/concepts/sessions.html index d41962366..8ab2f0748 100644 --- a/docs/2.0.0/concepts/sessions.html +++ b/docs/2.0.0/concepts/sessions.html @@ -4,7 +4,7 @@ Sessions | Serverpod - + diff --git a/docs/2.0.0/concepts/streams.html b/docs/2.0.0/concepts/streams.html index f43c79c59..b8cf5de45 100644 --- a/docs/2.0.0/concepts/streams.html +++ b/docs/2.0.0/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/2.0.0/concepts/webserver.html b/docs/2.0.0/concepts/webserver.html index ea2105143..23ce86bd6 100644 --- a/docs/2.0.0/concepts/webserver.html +++ b/docs/2.0.0/concepts/webserver.html @@ -4,7 +4,7 @@ Web server | Serverpod - + diff --git a/docs/2.0.0/concepts/working-with-endpoints.html b/docs/2.0.0/concepts/working-with-endpoints.html index 50e794fe1..ca70d115e 100644 --- a/docs/2.0.0/concepts/working-with-endpoints.html +++ b/docs/2.0.0/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/2.0.0/contribute.html b/docs/2.0.0/contribute.html index c23071a75..fbc232d70 100644 --- a/docs/2.0.0/contribute.html +++ b/docs/2.0.0/contribute.html @@ -4,7 +4,7 @@ Contribute | Serverpod - + diff --git a/docs/2.0.0/deployments/deploying-to-aws.html b/docs/2.0.0/deployments/deploying-to-aws.html index 2ff0974b0..7881b9278 100644 --- a/docs/2.0.0/deployments/deploying-to-aws.html +++ b/docs/2.0.0/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ AWS EC2 with Terraform | Serverpod - + diff --git a/docs/2.0.0/deployments/deploying-to-gce-terraform.html b/docs/2.0.0/deployments/deploying-to-gce-terraform.html index 7cec972ce..61f5a2d35 100644 --- a/docs/2.0.0/deployments/deploying-to-gce-terraform.html +++ b/docs/2.0.0/deployments/deploying-to-gce-terraform.html @@ -4,7 +4,7 @@ Google Cloud Engine with Terraform | Serverpod - + diff --git a/docs/2.0.0/deployments/deploying-to-gcr-console.html b/docs/2.0.0/deployments/deploying-to-gcr-console.html index 0d137af5c..23254e5b1 100644 --- a/docs/2.0.0/deployments/deploying-to-gcr-console.html +++ b/docs/2.0.0/deployments/deploying-to-gcr-console.html @@ -4,7 +4,7 @@ Google Cloud Run with CGP Console | Serverpod - + diff --git a/docs/2.0.0/deployments/deployment-strategy.html b/docs/2.0.0/deployments/deployment-strategy.html index dd32b7958..d21bc1652 100644 --- a/docs/2.0.0/deployments/deployment-strategy.html +++ b/docs/2.0.0/deployments/deployment-strategy.html @@ -4,7 +4,7 @@ Choosing deployment strategy | Serverpod - + diff --git a/docs/2.0.0/deployments/general.html b/docs/2.0.0/deployments/general.html index b2e46e857..430c6262c 100644 --- a/docs/2.0.0/deployments/general.html +++ b/docs/2.0.0/deployments/general.html @@ -4,7 +4,7 @@ Hosting elsewhere | Serverpod - + diff --git a/docs/2.0.0/get-started.html b/docs/2.0.0/get-started.html index 6cd8099a9..5319528eb 100644 --- a/docs/2.0.0/get-started.html +++ b/docs/2.0.0/get-started.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/2.0.0/roadmap.html b/docs/2.0.0/roadmap.html index 17da5f1a8..1522eec91 100644 --- a/docs/2.0.0/roadmap.html +++ b/docs/2.0.0/roadmap.html @@ -4,7 +4,7 @@ Roadmap | Serverpod - + diff --git a/docs/2.0.0/support.html b/docs/2.0.0/support.html index 22b1729ee..69e97cba9 100644 --- a/docs/2.0.0/support.html +++ b/docs/2.0.0/support.html @@ -4,7 +4,7 @@ Support & community | Serverpod - + diff --git a/docs/2.0.0/tools/cli.html b/docs/2.0.0/tools/cli.html index 1bdc0acb2..07dbc9381 100644 --- a/docs/2.0.0/tools/cli.html +++ b/docs/2.0.0/tools/cli.html @@ -4,7 +4,7 @@ Serverpod CLI | Serverpod - + diff --git a/docs/2.0.0/tools/insights.html b/docs/2.0.0/tools/insights.html index c2281e520..bb6510cdb 100644 --- a/docs/2.0.0/tools/insights.html +++ b/docs/2.0.0/tools/insights.html @@ -4,7 +4,7 @@ Serverpod Insights | Serverpod - + diff --git a/docs/2.0.0/tools/lsp.html b/docs/2.0.0/tools/lsp.html index eecebd77b..1b872db7d 100644 --- a/docs/2.0.0/tools/lsp.html +++ b/docs/2.0.0/tools/lsp.html @@ -4,7 +4,7 @@ Serverpod LSP | Serverpod - + diff --git a/docs/2.0.0/tutorials/authentication.html b/docs/2.0.0/tutorials/authentication.html index 1353785a7..19e32cc5c 100644 --- a/docs/2.0.0/tutorials/authentication.html +++ b/docs/2.0.0/tutorials/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/2.0.0/tutorials/code-example.html b/docs/2.0.0/tutorials/code-example.html index 9b0ae2720..958c17850 100644 --- a/docs/2.0.0/tutorials/code-example.html +++ b/docs/2.0.0/tutorials/code-example.html @@ -4,7 +4,7 @@ Code examples | Serverpod - + diff --git a/docs/2.0.0/tutorials/first-app.html b/docs/2.0.0/tutorials/first-app.html index 078add357..11e84a3f5 100644 --- a/docs/2.0.0/tutorials/first-app.html +++ b/docs/2.0.0/tutorials/first-app.html @@ -4,7 +4,7 @@ Build your first app | Serverpod - + diff --git a/docs/2.0.0/tutorials/videos.html b/docs/2.0.0/tutorials/videos.html index 8dc5504bb..8779eb70a 100644 --- a/docs/2.0.0/tutorials/videos.html +++ b/docs/2.0.0/tutorials/videos.html @@ -4,7 +4,7 @@ Videos | Serverpod - + diff --git a/docs/2.0.0/upgrading/upgrade-to-one-point-two.html b/docs/2.0.0/upgrading/upgrade-to-one-point-two.html index 03feebf53..20af71cee 100644 --- a/docs/2.0.0/upgrading/upgrade-to-one-point-two.html +++ b/docs/2.0.0/upgrading/upgrade-to-one-point-two.html @@ -4,7 +4,7 @@ Upgrade to 1.2 | Serverpod - + diff --git a/docs/2.0.0/upgrading/upgrade-to-two.html b/docs/2.0.0/upgrading/upgrade-to-two.html index d47475cfb..13433c408 100644 --- a/docs/2.0.0/upgrading/upgrade-to-two.html +++ b/docs/2.0.0/upgrading/upgrade-to-two.html @@ -4,7 +4,7 @@ Upgrade to 2.0 | Serverpod - + @@ -104,7 +104,7 @@

Updat

With the release of Serverpod 2.0, the fromJson constructor has been simplified and the serializationManager has been removed:

factory ClassName.fromJson(
Map<String, dynamic> json,
) {
return ClassName(
json['name'],
);
}

Deprecation Notice for SerializableEntity

-

The SerializableEntity class is deprecated and will be removed in version 2.1. Please implement the SerializableModel interface instead for creating serializable models.

+

The SerializableEntity class is deprecated and will be removed in version 3. Please implement the SerializableModel interface instead for creating serializable models.

Migration Guide

To migrate your code from SerializableEntity to SerializableModel, replace extends SerializableEntity with implements SerializableModel in your model classes.

Example

diff --git a/docs/404.html b/docs/404.html index 2b65b100b..e17a53eda 100644 --- a/docs/404.html +++ b/docs/404.html @@ -4,7 +4,7 @@ Serverpod - + diff --git a/docs/assets/js/1b218eaa.7f79a47a.js b/docs/assets/js/1b218eaa.4a46f698.js similarity index 99% rename from docs/assets/js/1b218eaa.7f79a47a.js rename to docs/assets/js/1b218eaa.4a46f698.js index 70c70601c..6c2094bd4 100644 --- a/docs/assets/js/1b218eaa.7f79a47a.js +++ b/docs/assets/js/1b218eaa.4a46f698.js @@ -1 +1 @@ -"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[57790],{2080:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>l,metadata:()=>r,toc:()=>c});var s=n(74848),d=n(28453);const l={},i="Working with models",r={id:"concepts/models",title:"Working with models",description:'Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular .yaml files within lib/src/models is supported, but it is recommended to use .spy.yaml (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the Serverpod Extension for VS Code.',source:"@site/versioned_docs/version-2.1.0/06-concepts/02-models.md",sourceDirName:"06-concepts",slug:"/concepts/models",permalink:"/concepts/models",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/versioned_docs/version-2.1.0/06-concepts/02-models.md",tags:[],version:"2.1.0",sidebarPosition:2,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Working with endpoints",permalink:"/concepts/working-with-endpoints"},next:{title:"Custom serialization",permalink:"/concepts/serialization"}},a={},c=[{value:"Class",id:"class",level:2},{value:"Limiting visibility of a generated class",id:"limiting-visibility-of-a-generated-class",level:3},{value:"Exception",id:"exception",level:2},{value:"Enum",id:"enum",level:2},{value:"Adding documentation",id:"adding-documentation",level:2},{value:"Generated code",id:"generated-code",level:2},{value:"copyWith",id:"copywith",level:3},{value:"toJson / fromJson",id:"tojson--fromjson",level:3},{value:"Custom methods",id:"custom-methods",level:3},{value:"Default Values",id:"default-values",level:2},{value:"Keywords",id:"keywords",level:3},{value:"How priorities work",id:"how-priorities-work",level:3},{value:"Supported default values",id:"supported-default-values",level:3},{value:"Boolean",id:"boolean",level:4},{value:"DateTime",id:"datetime",level:4},{value:"Double",id:"double",level:4},{value:"Duration",id:"duration",level:4},{value:"Enum",id:"enum-1",level:4},{value:"Integer",id:"integer",level:4},{value:"String",id:"string",level:4},{value:"UuidValue",id:"uuidvalue",level:4},{value:"Example",id:"example",level:3},{value:"Keywords",id:"keywords-1",level:2}];function o(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"working-with-models",children:"Working with models"})}),"\n",(0,s.jsxs)(t.p,{children:["Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular ",(0,s.jsx)(t.code,{children:".yaml"})," files within ",(0,s.jsx)(t.code,{children:"lib/src/models"})," is supported, but it is recommended to use ",(0,s.jsx)(t.code,{children:".spy.yaml"}),' (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the ',(0,s.jsx)(t.a,{href:"https://marketplace.visualstudio.com/items?itemName=serverpod.serverpod",children:"Serverpod Extension"})," for VS Code."]}),"\n",(0,s.jsx)(t.p,{children:"The files are analyzed by the Serverpod CLI when generating the project and creating migrations."}),"\n",(0,s.jsxs)(t.p,{children:["Run ",(0,s.jsx)(t.code,{children:"serverpod generate"})," to generate dart classes from the model files."]}),"\n",(0,s.jsx)(t.h2,{id:"class",children:"Class"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: Company\nfields:\n name: String\n foundedDate: DateTime?\n employees: List\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Supported types are ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/bool-class.html",children:"bool"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/int-class.html",children:"int"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/double-class.html",children:"double"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/String-class.html",children:"String"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Duration-class.html",children:"Duration"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/DateTime-class.html",children:"DateTime"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-typed_data/ByteData-class.html",children:"ByteData"}),", ",(0,s.jsx)(t.a,{href:"https://pub.dev/documentation/uuid/latest/uuid_value/UuidValue-class.html",children:"UuidValue"}),", and other serializable ",(0,s.jsx)(t.a,{href:"#class",children:"classes"}),", ",(0,s.jsx)(t.a,{href:"#exception",children:"exceptions"})," and ",(0,s.jsx)(t.a,{href:"#enum",children:"enums"}),". You can also use ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/List-class.html",children:"List"}),"s and ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Map-class.html",children:"Map"}),"s of the supported types, just make sure to specify the types. Null safety is supported. Once your classes are generated, you can use them as parameters or return types to endpoint methods."]}),"\n",(0,s.jsx)(t.h3,{id:"limiting-visibility-of-a-generated-class",children:"Limiting visibility of a generated class"}),"\n",(0,s.jsx)(t.p,{children:"By default, generated code for your serializable objects is available both on the server and the client. You may want to have the code on the server side only. E.g., if the serializable object is connected to a database table containing private information."}),"\n",(0,s.jsx)(t.p,{children:"To make a serializable class generated only on the server side, set the serverOnly property to true."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: MyPrivateClass\nserverOnly: true\nfields:\n hiddenSecretKey: String\n"})}),"\n",(0,s.jsxs)(t.p,{children:["It is also possible to set a ",(0,s.jsx)(t.code,{children:"scope"})," on a per-field basis. By default all fields are visible to both the server and the client. The available scopes are ",(0,s.jsx)(t.code,{children:"all"}),", ",(0,s.jsx)(t.code,{children:"serverOnly"}),", ",(0,s.jsx)(t.code,{children:"none"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: SelectivelyHiddenClass\nfields:\n hiddenSecretKey: String, scope=serverOnly\n publicKey: String\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["Serverpod's models can easily be saved to or read from the database. You can read more about this in the ",(0,s.jsx)(t.a,{href:"database/models",children:"Database"})," section."]})}),"\n",(0,s.jsx)(t.h2,{id:"exception",children:"Exception"}),"\n",(0,s.jsxs)(t.p,{children:["The Serverpod models supports creating exceptions that can be thrown in endpoints by using the ",(0,s.jsx)(t.code,{children:"exception"})," keyword. For more in-depth description on how to work with exceptions see ",(0,s.jsx)(t.a,{href:"exceptions",children:"Error handling and exceptions"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"exception: MyException\nfields:\n message: String\n errorType: MyEnum\n"})}),"\n",(0,s.jsx)(t.h2,{id:"enum",children:"Enum"}),"\n",(0,s.jsxs)(t.p,{children:["It is easy to add custom enums with serialization support by using the ",(0,s.jsx)(t.code,{children:"enum"})," keyword."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsx)(t.p,{children:"By default the serialization will convert the enum to an int representing the index of the value. Changing the order may therefore have unforeseen consequences when reusing old data (such as from a database). Changing the serialization to be based on the name instead of index is easy."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nserialized: byName\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.code,{children:"serialized"})," has two valid values ",(0,s.jsx)(t.code,{children:"byName"})," and ",(0,s.jsx)(t.code,{children:"byIndex"}),". When using ",(0,s.jsx)(t.code,{children:"byName"})," the string literal of the enum is used, when using ",(0,s.jsx)(t.code,{children:"byIndex"})," the index value (0, 1, 2, etc) is used."]}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["It's recommended to always set ",(0,s.jsx)(t.code,{children:"serialized"})," to ",(0,s.jsx)(t.code,{children:"byName"})," in any new Enum models, as this is less fragile and will be changed to the default setting in version 2 of Serverpod."]})}),"\n",(0,s.jsx)(t.h2,{id:"adding-documentation",children:"Adding documentation"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod allows you to add documentation to your serializable objects in a similar way that you would add documentation to your Dart code. Use three hashes (###) to indicate that a comment should be considered documentation."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"### Information about a company.\nclass: Company\nfields:\n ### The name of the company.\n name: String\n\n ### The date the company was founded, if known.\n foundedDate: DateTime?\n\n ### A list of people currently employed at the company.\n employees: List\n"})}),"\n",(0,s.jsx)(t.h2,{id:"generated-code",children:"Generated code"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod generates some convenience methods on the Dart classes."}),"\n",(0,s.jsx)(t.h3,{id:"copywith",children:"copyWith"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method allows for efficient object copying with selective field updates and is available on all generated ",(0,s.jsx)(t.code,{children:"class"}),"es. Here's how it operates:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"var john = User(name: 'John Doe', age: 25);\nvar jane = john.copyWith(name: 'Jane Doe');\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method generates a deep copy of an object, preserving all original fields unless explicitly modified. It can distinguish between a field set to ",(0,s.jsx)(t.code,{children:"null"})," and a field left unspecified (undefined). When using ",(0,s.jsx)(t.code,{children:"copyWith"}),", any field you don't update remains unchanged in the new object."]}),"\n",(0,s.jsx)(t.h3,{id:"tojson--fromjson",children:"toJson / fromJson"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"toJson"})," and ",(0,s.jsx)(t.code,{children:"fromJson"})," methods are generated on all models to help with serialization. Serverpod manages all serialization for you out of the box and you will rarely have to use these methods by your self. See the ",(0,s.jsx)(t.a,{href:"serialization",children:"Serialization"})," section for more info."]}),"\n",(0,s.jsx)(t.h3,{id:"custom-methods",children:"Custom methods"}),"\n",(0,s.jsxs)(t.p,{children:["Sometimes you will want to add custom methods to the generated classes. The easiest way to do this is with ",(0,s.jsx)(t.a,{href:"https://dart.dev/language/extension-methods",children:"Dart's extension feature"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"extension MyExtension on MyClass {\n bool isCustomMethod() {\n return true;\n }\n}\n"})}),"\n",(0,s.jsx)(t.h2,{id:"default-values",children:"Default Values"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod supports defining default values for fields in your models. These default values can be specified using three different keywords that determine how and where the defaults are applied:"}),"\n",(0,s.jsx)(t.h3,{id:"keywords",children:"Keywords"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"default"}),": This keyword sets a default value for both the model (code) and the database (persisted data). It acts as a general fallback if more specific defaults aren't provided."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"defaultModel"}),": This keyword sets a default value specifically for the model (the code side). If ",(0,s.jsx)(t.code,{children:"defaultModel"})," is not provided, the model will use the value specified by ",(0,s.jsx)(t.code,{children:"default"})," if it's available."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"defaultPersist"}),": This keyword sets a default value specifically for the database. If ",(0,s.jsx)(t.code,{children:"defaultPersist"})," is not provided, the database will use the value specified by ",(0,s.jsx)(t.code,{children:"default"})," if it's available."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"how-priorities-work",children:"How priorities work"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"For the model (code side):"})," If both ",(0,s.jsx)(t.code,{children:"defaultModel"})," and ",(0,s.jsx)(t.code,{children:"default"})," are provided, the model will use the ",(0,s.jsx)(t.code,{children:"defaultModel"})," value. If ",(0,s.jsx)(t.code,{children:"defaultModel"})," is not provided, it will fall back to using the ",(0,s.jsx)(t.code,{children:"default"})," value."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"For the database (persisted data):"})," If both ",(0,s.jsx)(t.code,{children:"defaultPersist"})," and ",(0,s.jsx)(t.code,{children:"default"})," are provided, the database will use the ",(0,s.jsx)(t.code,{children:"defaultPersist"})," value. If ",(0,s.jsx)(t.code,{children:"defaultPersist"})," is not provided, it will fall back to using the ",(0,s.jsx)(t.code,{children:"default"})," value."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"You can use these default values individually or in combination as needed. It is not required to use all default types for a field."}),"\n",(0,s.jsxs)(t.admonition,{type:"info",children:[(0,s.jsxs)(t.p,{children:["When using ",(0,s.jsx)(t.code,{children:"default"})," or ",(0,s.jsx)(t.code,{children:"defaultModel"})," in combination with ",(0,s.jsx)(t.code,{children:"defaultPersist"}),", it's important to understand how the interaction between these keywords affects the final value in the database."]}),(0,s.jsxs)(t.p,{children:["If you set a ",(0,s.jsx)(t.code,{children:"default"})," or ",(0,s.jsx)(t.code,{children:"defaultModel"})," value, the model's field or variable will have a value when it's passed to the database\u2014it will not be ",(0,s.jsx)(t.code,{children:"null"}),". Because of this, the SQL query will not use the ",(0,s.jsx)(t.code,{children:"defaultPersist"})," value since the field already has a value assigned by the model. In essence, assigning a ",(0,s.jsx)(t.code,{children:"default"})," or ",(0,s.jsx)(t.code,{children:"defaultModel"})," is like directly providing a value to the field, and the database will use this provided value instead of its own default."]}),(0,s.jsxs)(t.p,{children:["This means that ",(0,s.jsx)(t.code,{children:"defaultPersist"})," only comes into play when the model does not provide a value, allowing the database to apply its own default setting."]})]}),"\n",(0,s.jsx)(t.h3,{id:"supported-default-values",children:"Supported default values"}),"\n",(0,s.jsx)(t.h4,{id:"boolean",children:"Boolean"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Boolean"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"true"})," or ",(0,s.jsx)(t.code,{children:"false"})]}),(0,s.jsxs)(t.td,{children:["Sets the field to a boolean value, either ",(0,s.jsx)(t.code,{children:"true"})," or ",(0,s.jsx)(t.code,{children:"false"}),"."]})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"boolDefault: bool, default=true\n"})}),"\n",(0,s.jsx)(t.h4,{id:"datetime",children:"DateTime"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Current Date and Time"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"now"})}),(0,s.jsx)(t.td,{children:"Sets the field to the current date and time."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Specific UTC DateTime"})}),(0,s.jsxs)(t.td,{children:["UTC DateTime string in the format ",(0,s.jsx)(t.code,{children:"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"})]}),(0,s.jsx)(t.td,{children:"Sets the field to a specific date and time."})]})]})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"dateTimeDefaultNow: DateTime, default=now\ndateTimeDefaultUtc: DateTime, default=2024-05-01T22:00:00.000Z\n"})}),"\n",(0,s.jsx)(t.h4,{id:"double",children:"Double"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Double"})}),(0,s.jsx)(t.td,{children:"Any double value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific double value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"doubleDefault: double, default=10.5\n"})}),"\n",(0,s.jsx)(t.h4,{id:"duration",children:"Duration"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Specific Duration"})}),(0,s.jsxs)(t.td,{children:["A valid duration in the format ",(0,s.jsx)(t.code,{children:"Xd Xh Xmin Xs Xms"})]}),(0,s.jsxs)(t.td,{children:["Sets the field to a specific duration value. For example, ",(0,s.jsx)(t.code,{children:"1d 2h 10min 30s 100ms"})," represents 1 day, 2 hours, 10 minutes, 30 seconds, and 100 milliseconds."]})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"durationDefault: Duration, default=1d 2h 10min 30s 100ms\n"})}),"\n",(0,s.jsx)(t.h4,{id:"enum-1",children:"Enum"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Enum"})}),(0,s.jsx)(t.td,{children:"Any valid enum value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific enum value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: ByNameEnum\nserialized: byName\nvalues:\n - byName1\n - byName2\n"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: ByIndexEnum\nserialized: byIndex\nvalues:\n - byIndex1\n - byIndex2\n"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: EnumDefault\ntable: enum_default\nfields:\n byNameEnumDefault: ByNameEnum, default=byName1\n byIndexEnumDefault: ByIndexEnum, default=byIndex1\n"})}),"\n",(0,s.jsx)(t.p,{children:"In this example:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.code,{children:"byNameEnumDefault"})," field will default to ",(0,s.jsx)(t.code,{children:"'byName1'"})," in the database."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.code,{children:"byIndexEnumDefault"})," field will default to ",(0,s.jsx)(t.code,{children:"0"})," (the index of ",(0,s.jsx)(t.code,{children:"byIndex1"}),")."]}),"\n"]}),"\n",(0,s.jsx)(t.h4,{id:"integer",children:"Integer"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Integer"})}),(0,s.jsx)(t.td,{children:"Any integer value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific integer value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"intDefault: int, default=10\n"})}),"\n",(0,s.jsx)(t.h4,{id:"string",children:"String"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"String"})}),(0,s.jsx)(t.td,{children:"Any string value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific string value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"stringDefault: String, default='This is a string'\n"})}),"\n",(0,s.jsx)(t.h4,{id:"uuidvalue",children:"UuidValue"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Random UUID"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"random"})}),(0,s.jsxs)(t.td,{children:["Generates a random UUID. On the Dart side, ",(0,s.jsx)(t.code,{children:"Uuid().v4obj()"})," is used. On the database side, ",(0,s.jsx)(t.code,{children:"gen_random_uuid()"})," is used."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"UUID String"})}),(0,s.jsx)(t.td,{children:"A valid UUID version 4 string"}),(0,s.jsx)(t.td,{children:"Assigns a specific UUID to the field."})]})]})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"uuidDefaultRandom: UuidValue, default=random\nuuidDefaultUuid: UuidValue, default='550e8400-e29b-41d4-a716-446655440000'\n"})}),"\n",(0,s.jsx)(t.h3,{id:"example",children:"Example"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:'class: DefaultValue\ntable: default_value\nfields:\n ### Sets the current date and time as the default value.\n dateTimeDefault: DateTime, default=now\n\n ### Sets the default value for a boolean field.\n boolDefault: bool, defaultModel=false, defaultPersist=true\n\n ### Sets the default value for an integer field.\n intDefault: int, defaultPersist=20\n\n ### Sets the default value for a double field.\n doubleDefault: double, default=10.5, defaultPersist=20.5\n\n ### Sets the default value for a string field.\n stringDefault: String, default="This is a string", defaultModel="This is a string"\n'})}),"\n",(0,s.jsx)(t.h2,{id:"keywords-1",children:"Keywords"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:(0,s.jsx)(t.strong,{children:"Keyword"})}),(0,s.jsx)(t.th,{children:"Note"}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#class",children:"class"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#exception",children:"exception"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#enum",children:"enum"})})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"values"})})}),(0,s.jsx)(t.td,{children:"A special key for enums with a list of all enum values."}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"serialized"})})}),(0,s.jsx)(t.td,{children:"Sets the mode enums are serialized in"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"serverOnly"})})}),(0,s.jsx)(t.td,{children:"Boolean flag if code generator only should create the code for the server."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"table"})})}),(0,s.jsx)(t.td,{children:"A name for the database table, enables generation of database code."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/migrations#opt-out-of-migrations",children:(0,s.jsx)(t.strong,{children:"managedMigration"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to opt out of the database migration system."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"fields"})})}),(0,s.jsx)(t.td,{children:"All fields in the generated class should be listed here."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"type (fields)"})})}),(0,s.jsx)(t.td,{children:"Denotes the data type for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"scope"})})}),(0,s.jsx)(t.td,{children:"Denotes the scope for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"persist"})})}),(0,s.jsxs)(t.td,{children:["A boolean flag if the data should be stored in the database or not can be negated with ",(0,s.jsx)(t.code,{children:"!persist"})]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one",children:(0,s.jsx)(t.strong,{children:"relation"})})}),(0,s.jsx)(t.td,{children:"Sets a relation between model files, requires a table name to be set."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#bidirectional-relations",children:(0,s.jsx)(t.strong,{children:"name"})})}),(0,s.jsx)(t.td,{children:"Give a name to a relation to pair them."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#with-an-id-field",children:(0,s.jsx)(t.strong,{children:"parent"})})}),(0,s.jsx)(t.td,{children:"Sets the parent table on a relation."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#custom-foreign-key-field",children:(0,s.jsx)(t.strong,{children:"field"})})}),(0,s.jsx)(t.td,{children:"A manual specified foreign key field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onUpdate"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when updating data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onDelete"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when deleting data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#optional-relation",children:(0,s.jsx)(t.strong,{children:"optional"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to make a relation optional."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"indexes"})})}),(0,s.jsx)(t.td,{children:"Create indexes on your fields / columns."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"fields (index)"})})}),(0,s.jsx)(t.td,{children:"List the fields to create the indexes on."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"type (index)"})})}),(0,s.jsx)(t.td,{children:"The type of index to create."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"unique"})})}),(0,s.jsx)(t.td,{children:"Boolean flag to make the entries unique in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#default-values",children:(0,s.jsx)(t.strong,{children:"default"})})}),(0,s.jsxs)(t.td,{children:["Sets the default value for both the model and the database. This keyword cannot be used with ",(0,s.jsx)(t.strong,{children:"relation"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#default-values",children:(0,s.jsx)(t.strong,{children:"defaultModel"})})}),(0,s.jsxs)(t.td,{children:["Sets the default value for the model side. This keyword cannot be used with ",(0,s.jsx)(t.strong,{children:"relation"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#default-values",children:(0,s.jsx)(t.strong,{children:"defaultPersist"})})}),(0,s.jsxs)(t.td,{children:["Sets the default value for the database side. This keyword cannot be used with ",(0,s.jsx)(t.strong,{children:"relation"})," and ",(0,s.jsx)(t.strong,{children:"!persist"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,d.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(o,{...e})}):o(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var s=n(96540);const d={},l=s.createContext(d);function i(e){const t=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:i(e.components),s.createElement(l.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[57790],{2080:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>l,metadata:()=>r,toc:()=>c});var s=n(74848),d=n(28453);const l={},i="Working with models",r={id:"concepts/models",title:"Working with models",description:'Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular .yaml files within lib/src/models is supported, but it is recommended to use .spy.yaml (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the Serverpod Extension for VS Code.',source:"@site/versioned_docs/version-2.1.0/06-concepts/02-models.md",sourceDirName:"06-concepts",slug:"/concepts/models",permalink:"/concepts/models",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/versioned_docs/version-2.1.0/06-concepts/02-models.md",tags:[],version:"2.1.0",sidebarPosition:2,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Working with endpoints",permalink:"/concepts/working-with-endpoints"},next:{title:"Custom serialization",permalink:"/concepts/serialization"}},a={},c=[{value:"Class",id:"class",level:2},{value:"Limiting visibility of a generated class",id:"limiting-visibility-of-a-generated-class",level:3},{value:"Exception",id:"exception",level:2},{value:"Enum",id:"enum",level:2},{value:"Adding documentation",id:"adding-documentation",level:2},{value:"Generated code",id:"generated-code",level:2},{value:"copyWith",id:"copywith",level:3},{value:"toJson / fromJson",id:"tojson--fromjson",level:3},{value:"Custom methods",id:"custom-methods",level:3},{value:"Default Values",id:"default-values",level:2},{value:"Keywords",id:"keywords",level:3},{value:"How priorities work",id:"how-priorities-work",level:3},{value:"Supported default values",id:"supported-default-values",level:3},{value:"Boolean",id:"boolean",level:4},{value:"DateTime",id:"datetime",level:4},{value:"Double",id:"double",level:4},{value:"Duration",id:"duration",level:4},{value:"Enum",id:"enum-1",level:4},{value:"Integer",id:"integer",level:4},{value:"String",id:"string",level:4},{value:"UuidValue",id:"uuidvalue",level:4},{value:"Example",id:"example",level:3},{value:"Keywords",id:"keywords-1",level:2}];function o(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"working-with-models",children:"Working with models"})}),"\n",(0,s.jsxs)(t.p,{children:["Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular ",(0,s.jsx)(t.code,{children:".yaml"})," files within ",(0,s.jsx)(t.code,{children:"lib/src/models"})," is supported, but it is recommended to use ",(0,s.jsx)(t.code,{children:".spy.yaml"}),' (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the ',(0,s.jsx)(t.a,{href:"https://marketplace.visualstudio.com/items?itemName=serverpod.serverpod",children:"Serverpod Extension"})," for VS Code."]}),"\n",(0,s.jsx)(t.p,{children:"The files are analyzed by the Serverpod CLI when generating the project and creating migrations."}),"\n",(0,s.jsxs)(t.p,{children:["Run ",(0,s.jsx)(t.code,{children:"serverpod generate"})," to generate dart classes from the model files."]}),"\n",(0,s.jsx)(t.h2,{id:"class",children:"Class"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: Company\nfields:\n name: String\n foundedDate: DateTime?\n employees: List\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Supported types are ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/bool-class.html",children:"bool"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/int-class.html",children:"int"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/double-class.html",children:"double"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/String-class.html",children:"String"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Duration-class.html",children:"Duration"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/DateTime-class.html",children:"DateTime"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-typed_data/ByteData-class.html",children:"ByteData"}),", ",(0,s.jsx)(t.a,{href:"https://pub.dev/documentation/uuid/latest/uuid_value/UuidValue-class.html",children:"UuidValue"}),", and other serializable ",(0,s.jsx)(t.a,{href:"#class",children:"classes"}),", ",(0,s.jsx)(t.a,{href:"#exception",children:"exceptions"})," and ",(0,s.jsx)(t.a,{href:"#enum",children:"enums"}),". You can also use ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/List-class.html",children:"List"}),"s and ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Map-class.html",children:"Map"}),"s of the supported types, just make sure to specify the types. Null safety is supported. Once your classes are generated, you can use them as parameters or return types to endpoint methods."]}),"\n",(0,s.jsx)(t.h3,{id:"limiting-visibility-of-a-generated-class",children:"Limiting visibility of a generated class"}),"\n",(0,s.jsx)(t.p,{children:"By default, generated code for your serializable objects is available both on the server and the client. You may want to have the code on the server side only. E.g., if the serializable object is connected to a database table containing private information."}),"\n",(0,s.jsx)(t.p,{children:"To make a serializable class generated only on the server side, set the serverOnly property to true."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: MyPrivateClass\nserverOnly: true\nfields:\n hiddenSecretKey: String\n"})}),"\n",(0,s.jsxs)(t.p,{children:["It is also possible to set a ",(0,s.jsx)(t.code,{children:"scope"})," on a per-field basis. By default all fields are visible to both the server and the client. The available scopes are ",(0,s.jsx)(t.code,{children:"all"}),", ",(0,s.jsx)(t.code,{children:"serverOnly"}),", ",(0,s.jsx)(t.code,{children:"none"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: SelectivelyHiddenClass\nfields:\n hiddenSecretKey: String, scope=serverOnly\n publicKey: String\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["Serverpod's models can easily be saved to or read from the database. You can read more about this in the ",(0,s.jsx)(t.a,{href:"database/models",children:"Database"})," section."]})}),"\n",(0,s.jsx)(t.h2,{id:"exception",children:"Exception"}),"\n",(0,s.jsxs)(t.p,{children:["The Serverpod models supports creating exceptions that can be thrown in endpoints by using the ",(0,s.jsx)(t.code,{children:"exception"})," keyword. For more in-depth description on how to work with exceptions see ",(0,s.jsx)(t.a,{href:"exceptions",children:"Error handling and exceptions"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"exception: MyException\nfields:\n message: String\n errorType: MyEnum\n"})}),"\n",(0,s.jsx)(t.h2,{id:"enum",children:"Enum"}),"\n",(0,s.jsxs)(t.p,{children:["It is easy to add custom enums with serialization support by using the ",(0,s.jsx)(t.code,{children:"enum"})," keyword."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsx)(t.p,{children:"By default the serialization will convert the enum to an int representing the index of the value. Changing the order may therefore have unforeseen consequences when reusing old data (such as from a database). Changing the serialization to be based on the name instead of index is easy."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nserialized: byName\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.code,{children:"serialized"})," has two valid values ",(0,s.jsx)(t.code,{children:"byName"})," and ",(0,s.jsx)(t.code,{children:"byIndex"}),". When using ",(0,s.jsx)(t.code,{children:"byName"})," the string literal of the enum is used, when using ",(0,s.jsx)(t.code,{children:"byIndex"})," the index value (0, 1, 2, etc) is used."]}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["It's recommended to always set ",(0,s.jsx)(t.code,{children:"serialized"})," to ",(0,s.jsx)(t.code,{children:"byName"})," in any new Enum models, as this is less fragile and will be changed to the default setting in version 3 of Serverpod."]})}),"\n",(0,s.jsx)(t.h2,{id:"adding-documentation",children:"Adding documentation"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod allows you to add documentation to your serializable objects in a similar way that you would add documentation to your Dart code. Use three hashes (###) to indicate that a comment should be considered documentation."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"### Information about a company.\nclass: Company\nfields:\n ### The name of the company.\n name: String\n\n ### The date the company was founded, if known.\n foundedDate: DateTime?\n\n ### A list of people currently employed at the company.\n employees: List\n"})}),"\n",(0,s.jsx)(t.h2,{id:"generated-code",children:"Generated code"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod generates some convenience methods on the Dart classes."}),"\n",(0,s.jsx)(t.h3,{id:"copywith",children:"copyWith"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method allows for efficient object copying with selective field updates and is available on all generated ",(0,s.jsx)(t.code,{children:"class"}),"es. Here's how it operates:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"var john = User(name: 'John Doe', age: 25);\nvar jane = john.copyWith(name: 'Jane Doe');\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method generates a deep copy of an object, preserving all original fields unless explicitly modified. It can distinguish between a field set to ",(0,s.jsx)(t.code,{children:"null"})," and a field left unspecified (undefined). When using ",(0,s.jsx)(t.code,{children:"copyWith"}),", any field you don't update remains unchanged in the new object."]}),"\n",(0,s.jsx)(t.h3,{id:"tojson--fromjson",children:"toJson / fromJson"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"toJson"})," and ",(0,s.jsx)(t.code,{children:"fromJson"})," methods are generated on all models to help with serialization. Serverpod manages all serialization for you out of the box and you will rarely have to use these methods by your self. See the ",(0,s.jsx)(t.a,{href:"serialization",children:"Serialization"})," section for more info."]}),"\n",(0,s.jsx)(t.h3,{id:"custom-methods",children:"Custom methods"}),"\n",(0,s.jsxs)(t.p,{children:["Sometimes you will want to add custom methods to the generated classes. The easiest way to do this is with ",(0,s.jsx)(t.a,{href:"https://dart.dev/language/extension-methods",children:"Dart's extension feature"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"extension MyExtension on MyClass {\n bool isCustomMethod() {\n return true;\n }\n}\n"})}),"\n",(0,s.jsx)(t.h2,{id:"default-values",children:"Default Values"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod supports defining default values for fields in your models. These default values can be specified using three different keywords that determine how and where the defaults are applied:"}),"\n",(0,s.jsx)(t.h3,{id:"keywords",children:"Keywords"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"default"}),": This keyword sets a default value for both the model (code) and the database (persisted data). It acts as a general fallback if more specific defaults aren't provided."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"defaultModel"}),": This keyword sets a default value specifically for the model (the code side). If ",(0,s.jsx)(t.code,{children:"defaultModel"})," is not provided, the model will use the value specified by ",(0,s.jsx)(t.code,{children:"default"})," if it's available."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"defaultPersist"}),": This keyword sets a default value specifically for the database. If ",(0,s.jsx)(t.code,{children:"defaultPersist"})," is not provided, the database will use the value specified by ",(0,s.jsx)(t.code,{children:"default"})," if it's available."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"how-priorities-work",children:"How priorities work"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"For the model (code side):"})," If both ",(0,s.jsx)(t.code,{children:"defaultModel"})," and ",(0,s.jsx)(t.code,{children:"default"})," are provided, the model will use the ",(0,s.jsx)(t.code,{children:"defaultModel"})," value. If ",(0,s.jsx)(t.code,{children:"defaultModel"})," is not provided, it will fall back to using the ",(0,s.jsx)(t.code,{children:"default"})," value."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"For the database (persisted data):"})," If both ",(0,s.jsx)(t.code,{children:"defaultPersist"})," and ",(0,s.jsx)(t.code,{children:"default"})," are provided, the database will use the ",(0,s.jsx)(t.code,{children:"defaultPersist"})," value. If ",(0,s.jsx)(t.code,{children:"defaultPersist"})," is not provided, it will fall back to using the ",(0,s.jsx)(t.code,{children:"default"})," value."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"You can use these default values individually or in combination as needed. It is not required to use all default types for a field."}),"\n",(0,s.jsxs)(t.admonition,{type:"info",children:[(0,s.jsxs)(t.p,{children:["When using ",(0,s.jsx)(t.code,{children:"default"})," or ",(0,s.jsx)(t.code,{children:"defaultModel"})," in combination with ",(0,s.jsx)(t.code,{children:"defaultPersist"}),", it's important to understand how the interaction between these keywords affects the final value in the database."]}),(0,s.jsxs)(t.p,{children:["If you set a ",(0,s.jsx)(t.code,{children:"default"})," or ",(0,s.jsx)(t.code,{children:"defaultModel"})," value, the model's field or variable will have a value when it's passed to the database\u2014it will not be ",(0,s.jsx)(t.code,{children:"null"}),". Because of this, the SQL query will not use the ",(0,s.jsx)(t.code,{children:"defaultPersist"})," value since the field already has a value assigned by the model. In essence, assigning a ",(0,s.jsx)(t.code,{children:"default"})," or ",(0,s.jsx)(t.code,{children:"defaultModel"})," is like directly providing a value to the field, and the database will use this provided value instead of its own default."]}),(0,s.jsxs)(t.p,{children:["This means that ",(0,s.jsx)(t.code,{children:"defaultPersist"})," only comes into play when the model does not provide a value, allowing the database to apply its own default setting."]})]}),"\n",(0,s.jsx)(t.h3,{id:"supported-default-values",children:"Supported default values"}),"\n",(0,s.jsx)(t.h4,{id:"boolean",children:"Boolean"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Boolean"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"true"})," or ",(0,s.jsx)(t.code,{children:"false"})]}),(0,s.jsxs)(t.td,{children:["Sets the field to a boolean value, either ",(0,s.jsx)(t.code,{children:"true"})," or ",(0,s.jsx)(t.code,{children:"false"}),"."]})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"boolDefault: bool, default=true\n"})}),"\n",(0,s.jsx)(t.h4,{id:"datetime",children:"DateTime"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Current Date and Time"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"now"})}),(0,s.jsx)(t.td,{children:"Sets the field to the current date and time."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Specific UTC DateTime"})}),(0,s.jsxs)(t.td,{children:["UTC DateTime string in the format ",(0,s.jsx)(t.code,{children:"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"})]}),(0,s.jsx)(t.td,{children:"Sets the field to a specific date and time."})]})]})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"dateTimeDefaultNow: DateTime, default=now\ndateTimeDefaultUtc: DateTime, default=2024-05-01T22:00:00.000Z\n"})}),"\n",(0,s.jsx)(t.h4,{id:"double",children:"Double"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Double"})}),(0,s.jsx)(t.td,{children:"Any double value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific double value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"doubleDefault: double, default=10.5\n"})}),"\n",(0,s.jsx)(t.h4,{id:"duration",children:"Duration"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Specific Duration"})}),(0,s.jsxs)(t.td,{children:["A valid duration in the format ",(0,s.jsx)(t.code,{children:"Xd Xh Xmin Xs Xms"})]}),(0,s.jsxs)(t.td,{children:["Sets the field to a specific duration value. For example, ",(0,s.jsx)(t.code,{children:"1d 2h 10min 30s 100ms"})," represents 1 day, 2 hours, 10 minutes, 30 seconds, and 100 milliseconds."]})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"durationDefault: Duration, default=1d 2h 10min 30s 100ms\n"})}),"\n",(0,s.jsx)(t.h4,{id:"enum-1",children:"Enum"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Enum"})}),(0,s.jsx)(t.td,{children:"Any valid enum value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific enum value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: ByNameEnum\nserialized: byName\nvalues:\n - byName1\n - byName2\n"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: ByIndexEnum\nserialized: byIndex\nvalues:\n - byIndex1\n - byIndex2\n"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: EnumDefault\ntable: enum_default\nfields:\n byNameEnumDefault: ByNameEnum, default=byName1\n byIndexEnumDefault: ByIndexEnum, default=byIndex1\n"})}),"\n",(0,s.jsx)(t.p,{children:"In this example:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.code,{children:"byNameEnumDefault"})," field will default to ",(0,s.jsx)(t.code,{children:"'byName1'"})," in the database."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.code,{children:"byIndexEnumDefault"})," field will default to ",(0,s.jsx)(t.code,{children:"0"})," (the index of ",(0,s.jsx)(t.code,{children:"byIndex1"}),")."]}),"\n"]}),"\n",(0,s.jsx)(t.h4,{id:"integer",children:"Integer"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Integer"})}),(0,s.jsx)(t.td,{children:"Any integer value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific integer value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"intDefault: int, default=10\n"})}),"\n",(0,s.jsx)(t.h4,{id:"string",children:"String"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"String"})}),(0,s.jsx)(t.td,{children:"Any string value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific string value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"stringDefault: String, default='This is a string'\n"})}),"\n",(0,s.jsx)(t.h4,{id:"uuidvalue",children:"UuidValue"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Random UUID"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"random"})}),(0,s.jsxs)(t.td,{children:["Generates a random UUID. On the Dart side, ",(0,s.jsx)(t.code,{children:"Uuid().v4obj()"})," is used. On the database side, ",(0,s.jsx)(t.code,{children:"gen_random_uuid()"})," is used."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"UUID String"})}),(0,s.jsx)(t.td,{children:"A valid UUID version 4 string"}),(0,s.jsx)(t.td,{children:"Assigns a specific UUID to the field."})]})]})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"uuidDefaultRandom: UuidValue, default=random\nuuidDefaultUuid: UuidValue, default='550e8400-e29b-41d4-a716-446655440000'\n"})}),"\n",(0,s.jsx)(t.h3,{id:"example",children:"Example"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:'class: DefaultValue\ntable: default_value\nfields:\n ### Sets the current date and time as the default value.\n dateTimeDefault: DateTime, default=now\n\n ### Sets the default value for a boolean field.\n boolDefault: bool, defaultModel=false, defaultPersist=true\n\n ### Sets the default value for an integer field.\n intDefault: int, defaultPersist=20\n\n ### Sets the default value for a double field.\n doubleDefault: double, default=10.5, defaultPersist=20.5\n\n ### Sets the default value for a string field.\n stringDefault: String, default="This is a string", defaultModel="This is a string"\n'})}),"\n",(0,s.jsx)(t.h2,{id:"keywords-1",children:"Keywords"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:(0,s.jsx)(t.strong,{children:"Keyword"})}),(0,s.jsx)(t.th,{children:"Note"}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#class",children:"class"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#exception",children:"exception"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#enum",children:"enum"})})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"values"})})}),(0,s.jsx)(t.td,{children:"A special key for enums with a list of all enum values."}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"serialized"})})}),(0,s.jsx)(t.td,{children:"Sets the mode enums are serialized in"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"serverOnly"})})}),(0,s.jsx)(t.td,{children:"Boolean flag if code generator only should create the code for the server."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"table"})})}),(0,s.jsx)(t.td,{children:"A name for the database table, enables generation of database code."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/migrations#opt-out-of-migrations",children:(0,s.jsx)(t.strong,{children:"managedMigration"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to opt out of the database migration system."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"fields"})})}),(0,s.jsx)(t.td,{children:"All fields in the generated class should be listed here."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"type (fields)"})})}),(0,s.jsx)(t.td,{children:"Denotes the data type for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"scope"})})}),(0,s.jsx)(t.td,{children:"Denotes the scope for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"persist"})})}),(0,s.jsxs)(t.td,{children:["A boolean flag if the data should be stored in the database or not can be negated with ",(0,s.jsx)(t.code,{children:"!persist"})]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one",children:(0,s.jsx)(t.strong,{children:"relation"})})}),(0,s.jsx)(t.td,{children:"Sets a relation between model files, requires a table name to be set."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#bidirectional-relations",children:(0,s.jsx)(t.strong,{children:"name"})})}),(0,s.jsx)(t.td,{children:"Give a name to a relation to pair them."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#with-an-id-field",children:(0,s.jsx)(t.strong,{children:"parent"})})}),(0,s.jsx)(t.td,{children:"Sets the parent table on a relation."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#custom-foreign-key-field",children:(0,s.jsx)(t.strong,{children:"field"})})}),(0,s.jsx)(t.td,{children:"A manual specified foreign key field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onUpdate"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when updating data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onDelete"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when deleting data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#optional-relation",children:(0,s.jsx)(t.strong,{children:"optional"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to make a relation optional."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"indexes"})})}),(0,s.jsx)(t.td,{children:"Create indexes on your fields / columns."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"fields (index)"})})}),(0,s.jsx)(t.td,{children:"List the fields to create the indexes on."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"type (index)"})})}),(0,s.jsx)(t.td,{children:"The type of index to create."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"unique"})})}),(0,s.jsx)(t.td,{children:"Boolean flag to make the entries unique in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#default-values",children:(0,s.jsx)(t.strong,{children:"default"})})}),(0,s.jsxs)(t.td,{children:["Sets the default value for both the model and the database. This keyword cannot be used with ",(0,s.jsx)(t.strong,{children:"relation"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#default-values",children:(0,s.jsx)(t.strong,{children:"defaultModel"})})}),(0,s.jsxs)(t.td,{children:["Sets the default value for the model side. This keyword cannot be used with ",(0,s.jsx)(t.strong,{children:"relation"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#default-values",children:(0,s.jsx)(t.strong,{children:"defaultPersist"})})}),(0,s.jsxs)(t.td,{children:["Sets the default value for the database side. This keyword cannot be used with ",(0,s.jsx)(t.strong,{children:"relation"})," and ",(0,s.jsx)(t.strong,{children:"!persist"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,d.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(o,{...e})}):o(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var s=n(96540);const d={},l=s.createContext(d);function i(e){const t=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:i(e.components),s.createElement(l.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/32b8fafb.d51c7aa0.js b/docs/assets/js/32b8fafb.439ef5f1.js similarity index 99% rename from docs/assets/js/32b8fafb.d51c7aa0.js rename to docs/assets/js/32b8fafb.439ef5f1.js index 2ac109154..0f99f6659 100644 --- a/docs/assets/js/32b8fafb.d51c7aa0.js +++ b/docs/assets/js/32b8fafb.439ef5f1.js @@ -1 +1 @@ -"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[92113],{82853:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>l,metadata:()=>r,toc:()=>c});var s=n(74848),d=n(28453);const l={},i="Working with models",r={id:"concepts/models",title:"Working with models",description:'Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular .yaml files within lib/src/models is supported, but it is recommended to use .spy.yaml (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the Serverpod Extension for VS Code.',source:"@site/docs/06-concepts/02-models.md",sourceDirName:"06-concepts",slug:"/concepts/models",permalink:"/next/concepts/models",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/docs/06-concepts/02-models.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Working with endpoints",permalink:"/next/concepts/working-with-endpoints"},next:{title:"Custom serialization",permalink:"/next/concepts/serialization"}},a={},c=[{value:"Class",id:"class",level:2},{value:"Limiting visibility of a generated class",id:"limiting-visibility-of-a-generated-class",level:3},{value:"Exception",id:"exception",level:2},{value:"Enum",id:"enum",level:2},{value:"Adding documentation",id:"adding-documentation",level:2},{value:"Generated code",id:"generated-code",level:2},{value:"copyWith",id:"copywith",level:3},{value:"toJson / fromJson",id:"tojson--fromjson",level:3},{value:"Custom methods",id:"custom-methods",level:3},{value:"Default Values",id:"default-values",level:2},{value:"Keywords",id:"keywords",level:3},{value:"How priorities work",id:"how-priorities-work",level:3},{value:"Supported default values",id:"supported-default-values",level:3},{value:"Boolean",id:"boolean",level:4},{value:"DateTime",id:"datetime",level:4},{value:"Double",id:"double",level:4},{value:"Duration",id:"duration",level:4},{value:"Enum",id:"enum-1",level:4},{value:"Integer",id:"integer",level:4},{value:"String",id:"string",level:4},{value:"UuidValue",id:"uuidvalue",level:4},{value:"Example",id:"example",level:3},{value:"Keywords",id:"keywords-1",level:2}];function o(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"working-with-models",children:"Working with models"})}),"\n",(0,s.jsxs)(t.p,{children:["Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular ",(0,s.jsx)(t.code,{children:".yaml"})," files within ",(0,s.jsx)(t.code,{children:"lib/src/models"})," is supported, but it is recommended to use ",(0,s.jsx)(t.code,{children:".spy.yaml"}),' (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the ',(0,s.jsx)(t.a,{href:"https://marketplace.visualstudio.com/items?itemName=serverpod.serverpod",children:"Serverpod Extension"})," for VS Code."]}),"\n",(0,s.jsx)(t.p,{children:"The files are analyzed by the Serverpod CLI when generating the project and creating migrations."}),"\n",(0,s.jsxs)(t.p,{children:["Run ",(0,s.jsx)(t.code,{children:"serverpod generate"})," to generate dart classes from the model files."]}),"\n",(0,s.jsx)(t.h2,{id:"class",children:"Class"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: Company\nfields:\n name: String\n foundedDate: DateTime?\n employees: List\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Supported types are ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/bool-class.html",children:"bool"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/int-class.html",children:"int"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/double-class.html",children:"double"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/String-class.html",children:"String"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Duration-class.html",children:"Duration"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/DateTime-class.html",children:"DateTime"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-typed_data/ByteData-class.html",children:"ByteData"}),", ",(0,s.jsx)(t.a,{href:"https://pub.dev/documentation/uuid/latest/uuid_value/UuidValue-class.html",children:"UuidValue"}),", and other serializable ",(0,s.jsx)(t.a,{href:"#class",children:"classes"}),", ",(0,s.jsx)(t.a,{href:"#exception",children:"exceptions"})," and ",(0,s.jsx)(t.a,{href:"#enum",children:"enums"}),". You can also use ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/List-class.html",children:"List"}),"s and ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Map-class.html",children:"Map"}),"s of the supported types, just make sure to specify the types. Null safety is supported. Once your classes are generated, you can use them as parameters or return types to endpoint methods."]}),"\n",(0,s.jsx)(t.h3,{id:"limiting-visibility-of-a-generated-class",children:"Limiting visibility of a generated class"}),"\n",(0,s.jsx)(t.p,{children:"By default, generated code for your serializable objects is available both on the server and the client. You may want to have the code on the server side only. E.g., if the serializable object is connected to a database table containing private information."}),"\n",(0,s.jsx)(t.p,{children:"To make a serializable class generated only on the server side, set the serverOnly property to true."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: MyPrivateClass\nserverOnly: true\nfields:\n hiddenSecretKey: String\n"})}),"\n",(0,s.jsxs)(t.p,{children:["It is also possible to set a ",(0,s.jsx)(t.code,{children:"scope"})," on a per-field basis. By default all fields are visible to both the server and the client. The available scopes are ",(0,s.jsx)(t.code,{children:"all"}),", ",(0,s.jsx)(t.code,{children:"serverOnly"}),", ",(0,s.jsx)(t.code,{children:"none"}),"."]}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"none"})," is not typically used in serverpod apps. It is intended for the serverpod framework, itself."]})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: SelectivelyHiddenClass\nfields:\n hiddenSecretKey: String, scope=serverOnly\n publicKey: String\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["Serverpod's models can easily be saved to or read from the database. You can read more about this in the ",(0,s.jsx)(t.a,{href:"database/models",children:"Database"})," section."]})}),"\n",(0,s.jsx)(t.h2,{id:"exception",children:"Exception"}),"\n",(0,s.jsxs)(t.p,{children:["The Serverpod models supports creating exceptions that can be thrown in endpoints by using the ",(0,s.jsx)(t.code,{children:"exception"})," keyword. For more in-depth description on how to work with exceptions see ",(0,s.jsx)(t.a,{href:"exceptions",children:"Error handling and exceptions"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"exception: MyException\nfields:\n message: String\n errorType: MyEnum\n"})}),"\n",(0,s.jsx)(t.h2,{id:"enum",children:"Enum"}),"\n",(0,s.jsxs)(t.p,{children:["It is easy to add custom enums with serialization support by using the ",(0,s.jsx)(t.code,{children:"enum"})," keyword."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsx)(t.p,{children:"By default the serialization will convert the enum to an int representing the index of the value. Changing the order may therefore have unforeseen consequences when reusing old data (such as from a database). Changing the serialization to be based on the name instead of index is easy."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nserialized: byName\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.code,{children:"serialized"})," has two valid values ",(0,s.jsx)(t.code,{children:"byName"})," and ",(0,s.jsx)(t.code,{children:"byIndex"}),". When using ",(0,s.jsx)(t.code,{children:"byName"})," the string literal of the enum is used, when using ",(0,s.jsx)(t.code,{children:"byIndex"})," the index value (0, 1, 2, etc) is used."]}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["It's recommended to always set ",(0,s.jsx)(t.code,{children:"serialized"})," to ",(0,s.jsx)(t.code,{children:"byName"})," in any new Enum models, as this is less fragile and will be changed to the default setting in version 2 of Serverpod."]})}),"\n",(0,s.jsx)(t.h2,{id:"adding-documentation",children:"Adding documentation"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod allows you to add documentation to your serializable objects in a similar way that you would add documentation to your Dart code. Use three hashes (###) to indicate that a comment should be considered documentation."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"### Information about a company.\nclass: Company\nfields:\n ### The name of the company.\n name: String\n\n ### The date the company was founded, if known.\n foundedDate: DateTime?\n\n ### A list of people currently employed at the company.\n employees: List\n"})}),"\n",(0,s.jsx)(t.h2,{id:"generated-code",children:"Generated code"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod generates some convenience methods on the Dart classes."}),"\n",(0,s.jsx)(t.h3,{id:"copywith",children:"copyWith"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method allows for efficient object copying with selective field updates and is available on all generated ",(0,s.jsx)(t.code,{children:"class"}),"es. Here's how it operates:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"var john = User(name: 'John Doe', age: 25);\nvar jane = john.copyWith(name: 'Jane Doe');\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method generates a deep copy of an object, preserving all original fields unless explicitly modified. It can distinguish between a field set to ",(0,s.jsx)(t.code,{children:"null"})," and a field left unspecified (undefined). When using ",(0,s.jsx)(t.code,{children:"copyWith"}),", any field you don't update remains unchanged in the new object."]}),"\n",(0,s.jsx)(t.h3,{id:"tojson--fromjson",children:"toJson / fromJson"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"toJson"})," and ",(0,s.jsx)(t.code,{children:"fromJson"})," methods are generated on all models to help with serialization. Serverpod manages all serialization for you out of the box and you will rarely have to use these methods by your self. See the ",(0,s.jsx)(t.a,{href:"serialization",children:"Serialization"})," section for more info."]}),"\n",(0,s.jsx)(t.h3,{id:"custom-methods",children:"Custom methods"}),"\n",(0,s.jsxs)(t.p,{children:["Sometimes you will want to add custom methods to the generated classes. The easiest way to do this is with ",(0,s.jsx)(t.a,{href:"https://dart.dev/language/extension-methods",children:"Dart's extension feature"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"extension MyExtension on MyClass {\n bool isCustomMethod() {\n return true;\n }\n}\n"})}),"\n",(0,s.jsx)(t.h2,{id:"default-values",children:"Default Values"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod supports defining default values for fields in your models. These default values can be specified using three different keywords that determine how and where the defaults are applied:"}),"\n",(0,s.jsx)(t.h3,{id:"keywords",children:"Keywords"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"default"}),": This keyword sets a default value for both the model (code) and the database (persisted data). It acts as a general fallback if more specific defaults aren't provided."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"defaultModel"}),": This keyword sets a default value specifically for the model (the code side). If ",(0,s.jsx)(t.code,{children:"defaultModel"})," is not provided, the model will use the value specified by ",(0,s.jsx)(t.code,{children:"default"})," if it's available."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"defaultPersist"}),": This keyword sets a default value specifically for the database. If ",(0,s.jsx)(t.code,{children:"defaultPersist"})," is not provided, the database will use the value specified by ",(0,s.jsx)(t.code,{children:"default"})," if it's available."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"how-priorities-work",children:"How priorities work"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"For the model (code side):"})," If both ",(0,s.jsx)(t.code,{children:"defaultModel"})," and ",(0,s.jsx)(t.code,{children:"default"})," are provided, the model will use the ",(0,s.jsx)(t.code,{children:"defaultModel"})," value. If ",(0,s.jsx)(t.code,{children:"defaultModel"})," is not provided, it will fall back to using the ",(0,s.jsx)(t.code,{children:"default"})," value."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"For the database (persisted data):"})," If both ",(0,s.jsx)(t.code,{children:"defaultPersist"})," and ",(0,s.jsx)(t.code,{children:"default"})," are provided, the database will use the ",(0,s.jsx)(t.code,{children:"defaultPersist"})," value. If ",(0,s.jsx)(t.code,{children:"defaultPersist"})," is not provided, it will fall back to using the ",(0,s.jsx)(t.code,{children:"default"})," value."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"You can use these default values individually or in combination as needed. It is not required to use all default types for a field."}),"\n",(0,s.jsxs)(t.admonition,{type:"info",children:[(0,s.jsxs)(t.p,{children:["When using ",(0,s.jsx)(t.code,{children:"default"})," or ",(0,s.jsx)(t.code,{children:"defaultModel"})," in combination with ",(0,s.jsx)(t.code,{children:"defaultPersist"}),", it's important to understand how the interaction between these keywords affects the final value in the database."]}),(0,s.jsxs)(t.p,{children:["If you set a ",(0,s.jsx)(t.code,{children:"default"})," or ",(0,s.jsx)(t.code,{children:"defaultModel"})," value, the model's field or variable will have a value when it's passed to the database\u2014it will not be ",(0,s.jsx)(t.code,{children:"null"}),". Because of this, the SQL query will not use the ",(0,s.jsx)(t.code,{children:"defaultPersist"})," value since the field already has a value assigned by the model. In essence, assigning a ",(0,s.jsx)(t.code,{children:"default"})," or ",(0,s.jsx)(t.code,{children:"defaultModel"})," is like directly providing a value to the field, and the database will use this provided value instead of its own default."]}),(0,s.jsxs)(t.p,{children:["This means that ",(0,s.jsx)(t.code,{children:"defaultPersist"})," only comes into play when the model does not provide a value, allowing the database to apply its own default setting."]})]}),"\n",(0,s.jsx)(t.h3,{id:"supported-default-values",children:"Supported default values"}),"\n",(0,s.jsx)(t.h4,{id:"boolean",children:"Boolean"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Boolean"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"true"})," or ",(0,s.jsx)(t.code,{children:"false"})]}),(0,s.jsxs)(t.td,{children:["Sets the field to a boolean value, either ",(0,s.jsx)(t.code,{children:"true"})," or ",(0,s.jsx)(t.code,{children:"false"}),"."]})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"boolDefault: bool, default=true\n"})}),"\n",(0,s.jsx)(t.h4,{id:"datetime",children:"DateTime"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Current Date and Time"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"now"})}),(0,s.jsx)(t.td,{children:"Sets the field to the current date and time."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Specific UTC DateTime"})}),(0,s.jsxs)(t.td,{children:["UTC DateTime string in the format ",(0,s.jsx)(t.code,{children:"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"})]}),(0,s.jsx)(t.td,{children:"Sets the field to a specific date and time."})]})]})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"dateTimeDefaultNow: DateTime, default=now\ndateTimeDefaultUtc: DateTime, default=2024-05-01T22:00:00.000Z\n"})}),"\n",(0,s.jsx)(t.h4,{id:"double",children:"Double"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Double"})}),(0,s.jsx)(t.td,{children:"Any double value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific double value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"doubleDefault: double, default=10.5\n"})}),"\n",(0,s.jsx)(t.h4,{id:"duration",children:"Duration"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Specific Duration"})}),(0,s.jsxs)(t.td,{children:["A valid duration in the format ",(0,s.jsx)(t.code,{children:"Xd Xh Xmin Xs Xms"})]}),(0,s.jsxs)(t.td,{children:["Sets the field to a specific duration value. For example, ",(0,s.jsx)(t.code,{children:"1d 2h 10min 30s 100ms"})," represents 1 day, 2 hours, 10 minutes, 30 seconds, and 100 milliseconds."]})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"durationDefault: Duration, default=1d 2h 10min 30s 100ms\n"})}),"\n",(0,s.jsx)(t.h4,{id:"enum-1",children:"Enum"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Enum"})}),(0,s.jsx)(t.td,{children:"Any valid enum value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific enum value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: ByNameEnum\nserialized: byName\nvalues:\n - byName1\n - byName2\n"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: ByIndexEnum\nserialized: byIndex\nvalues:\n - byIndex1\n - byIndex2\n"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: EnumDefault\ntable: enum_default\nfields:\n byNameEnumDefault: ByNameEnum, default=byName1\n byIndexEnumDefault: ByIndexEnum, default=byIndex1\n"})}),"\n",(0,s.jsx)(t.p,{children:"In this example:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.code,{children:"byNameEnumDefault"})," field will default to ",(0,s.jsx)(t.code,{children:"'byName1'"})," in the database."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.code,{children:"byIndexEnumDefault"})," field will default to ",(0,s.jsx)(t.code,{children:"0"})," (the index of ",(0,s.jsx)(t.code,{children:"byIndex1"}),")."]}),"\n"]}),"\n",(0,s.jsx)(t.h4,{id:"integer",children:"Integer"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Integer"})}),(0,s.jsx)(t.td,{children:"Any integer value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific integer value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"intDefault: int, default=10\n"})}),"\n",(0,s.jsx)(t.h4,{id:"string",children:"String"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"String"})}),(0,s.jsx)(t.td,{children:"Any string value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific string value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"stringDefault: String, default='This is a string'\n"})}),"\n",(0,s.jsx)(t.h4,{id:"uuidvalue",children:"UuidValue"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Random UUID"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"random"})}),(0,s.jsxs)(t.td,{children:["Generates a random UUID. On the Dart side, ",(0,s.jsx)(t.code,{children:"Uuid().v4obj()"})," is used. On the database side, ",(0,s.jsx)(t.code,{children:"gen_random_uuid()"})," is used."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"UUID String"})}),(0,s.jsx)(t.td,{children:"A valid UUID version 4 string"}),(0,s.jsx)(t.td,{children:"Assigns a specific UUID to the field."})]})]})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"uuidDefaultRandom: UuidValue, default=random\nuuidDefaultUuid: UuidValue, default='550e8400-e29b-41d4-a716-446655440000'\n"})}),"\n",(0,s.jsx)(t.h3,{id:"example",children:"Example"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:'class: DefaultValue\ntable: default_value\nfields:\n ### Sets the current date and time as the default value.\n dateTimeDefault: DateTime, default=now\n\n ### Sets the default value for a boolean field.\n boolDefault: bool, defaultModel=false, defaultPersist=true\n\n ### Sets the default value for an integer field.\n intDefault: int, defaultPersist=20\n\n ### Sets the default value for a double field.\n doubleDefault: double, default=10.5, defaultPersist=20.5\n\n ### Sets the default value for a string field.\n stringDefault: String, default="This is a string", defaultModel="This is a string"\n'})}),"\n",(0,s.jsx)(t.h2,{id:"keywords-1",children:"Keywords"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:(0,s.jsx)(t.strong,{children:"Keyword"})}),(0,s.jsx)(t.th,{children:"Note"}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#class",children:"class"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#exception",children:"exception"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#enum",children:"enum"})})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"values"})})}),(0,s.jsx)(t.td,{children:"A special key for enums with a list of all enum values."}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"serialized"})})}),(0,s.jsx)(t.td,{children:"Sets the mode enums are serialized in"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"serverOnly"})})}),(0,s.jsx)(t.td,{children:"Boolean flag if code generator only should create the code for the server."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"table"})})}),(0,s.jsx)(t.td,{children:"A name for the database table, enables generation of database code."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/migrations#opt-out-of-migrations",children:(0,s.jsx)(t.strong,{children:"managedMigration"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to opt out of the database migration system."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"fields"})})}),(0,s.jsx)(t.td,{children:"All fields in the generated class should be listed here."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"type (fields)"})})}),(0,s.jsx)(t.td,{children:"Denotes the data type for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"scope"})})}),(0,s.jsx)(t.td,{children:"Denotes the scope for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"persist"})})}),(0,s.jsxs)(t.td,{children:["A boolean flag if the data should be stored in the database or not can be negated with ",(0,s.jsx)(t.code,{children:"!persist"})]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one",children:(0,s.jsx)(t.strong,{children:"relation"})})}),(0,s.jsx)(t.td,{children:"Sets a relation between model files, requires a table name to be set."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#bidirectional-relations",children:(0,s.jsx)(t.strong,{children:"name"})})}),(0,s.jsx)(t.td,{children:"Give a name to a relation to pair them."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#with-an-id-field",children:(0,s.jsx)(t.strong,{children:"parent"})})}),(0,s.jsx)(t.td,{children:"Sets the parent table on a relation."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#custom-foreign-key-field",children:(0,s.jsx)(t.strong,{children:"field"})})}),(0,s.jsx)(t.td,{children:"A manual specified foreign key field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onUpdate"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when updating data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onDelete"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when deleting data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#optional-relation",children:(0,s.jsx)(t.strong,{children:"optional"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to make a relation optional."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"indexes"})})}),(0,s.jsx)(t.td,{children:"Create indexes on your fields / columns."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"fields (index)"})})}),(0,s.jsx)(t.td,{children:"List the fields to create the indexes on."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"type (index)"})})}),(0,s.jsx)(t.td,{children:"The type of index to create."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"unique"})})}),(0,s.jsx)(t.td,{children:"Boolean flag to make the entries unique in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#default-values",children:(0,s.jsx)(t.strong,{children:"default"})})}),(0,s.jsxs)(t.td,{children:["Sets the default value for both the model and the database. This keyword cannot be used with ",(0,s.jsx)(t.strong,{children:"relation"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#default-values",children:(0,s.jsx)(t.strong,{children:"defaultModel"})})}),(0,s.jsxs)(t.td,{children:["Sets the default value for the model side. This keyword cannot be used with ",(0,s.jsx)(t.strong,{children:"relation"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#default-values",children:(0,s.jsx)(t.strong,{children:"defaultPersist"})})}),(0,s.jsxs)(t.td,{children:["Sets the default value for the database side. This keyword cannot be used with ",(0,s.jsx)(t.strong,{children:"relation"})," and ",(0,s.jsx)(t.strong,{children:"!persist"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,d.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(o,{...e})}):o(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var s=n(96540);const d={},l=s.createContext(d);function i(e){const t=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:i(e.components),s.createElement(l.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[92113],{82853:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>l,metadata:()=>r,toc:()=>c});var s=n(74848),d=n(28453);const l={},i="Working with models",r={id:"concepts/models",title:"Working with models",description:'Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular .yaml files within lib/src/models is supported, but it is recommended to use .spy.yaml (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the Serverpod Extension for VS Code.',source:"@site/docs/06-concepts/02-models.md",sourceDirName:"06-concepts",slug:"/concepts/models",permalink:"/next/concepts/models",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/docs/06-concepts/02-models.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Working with endpoints",permalink:"/next/concepts/working-with-endpoints"},next:{title:"Custom serialization",permalink:"/next/concepts/serialization"}},a={},c=[{value:"Class",id:"class",level:2},{value:"Limiting visibility of a generated class",id:"limiting-visibility-of-a-generated-class",level:3},{value:"Exception",id:"exception",level:2},{value:"Enum",id:"enum",level:2},{value:"Adding documentation",id:"adding-documentation",level:2},{value:"Generated code",id:"generated-code",level:2},{value:"copyWith",id:"copywith",level:3},{value:"toJson / fromJson",id:"tojson--fromjson",level:3},{value:"Custom methods",id:"custom-methods",level:3},{value:"Default Values",id:"default-values",level:2},{value:"Keywords",id:"keywords",level:3},{value:"How priorities work",id:"how-priorities-work",level:3},{value:"Supported default values",id:"supported-default-values",level:3},{value:"Boolean",id:"boolean",level:4},{value:"DateTime",id:"datetime",level:4},{value:"Double",id:"double",level:4},{value:"Duration",id:"duration",level:4},{value:"Enum",id:"enum-1",level:4},{value:"Integer",id:"integer",level:4},{value:"String",id:"string",level:4},{value:"UuidValue",id:"uuidvalue",level:4},{value:"Example",id:"example",level:3},{value:"Keywords",id:"keywords-1",level:2}];function o(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"working-with-models",children:"Working with models"})}),"\n",(0,s.jsxs)(t.p,{children:["Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular ",(0,s.jsx)(t.code,{children:".yaml"})," files within ",(0,s.jsx)(t.code,{children:"lib/src/models"})," is supported, but it is recommended to use ",(0,s.jsx)(t.code,{children:".spy.yaml"}),' (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the ',(0,s.jsx)(t.a,{href:"https://marketplace.visualstudio.com/items?itemName=serverpod.serverpod",children:"Serverpod Extension"})," for VS Code."]}),"\n",(0,s.jsx)(t.p,{children:"The files are analyzed by the Serverpod CLI when generating the project and creating migrations."}),"\n",(0,s.jsxs)(t.p,{children:["Run ",(0,s.jsx)(t.code,{children:"serverpod generate"})," to generate dart classes from the model files."]}),"\n",(0,s.jsx)(t.h2,{id:"class",children:"Class"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: Company\nfields:\n name: String\n foundedDate: DateTime?\n employees: List\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Supported types are ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/bool-class.html",children:"bool"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/int-class.html",children:"int"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/double-class.html",children:"double"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/String-class.html",children:"String"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Duration-class.html",children:"Duration"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/DateTime-class.html",children:"DateTime"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-typed_data/ByteData-class.html",children:"ByteData"}),", ",(0,s.jsx)(t.a,{href:"https://pub.dev/documentation/uuid/latest/uuid_value/UuidValue-class.html",children:"UuidValue"}),", and other serializable ",(0,s.jsx)(t.a,{href:"#class",children:"classes"}),", ",(0,s.jsx)(t.a,{href:"#exception",children:"exceptions"})," and ",(0,s.jsx)(t.a,{href:"#enum",children:"enums"}),". You can also use ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/List-class.html",children:"List"}),"s and ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Map-class.html",children:"Map"}),"s of the supported types, just make sure to specify the types. Null safety is supported. Once your classes are generated, you can use them as parameters or return types to endpoint methods."]}),"\n",(0,s.jsx)(t.h3,{id:"limiting-visibility-of-a-generated-class",children:"Limiting visibility of a generated class"}),"\n",(0,s.jsx)(t.p,{children:"By default, generated code for your serializable objects is available both on the server and the client. You may want to have the code on the server side only. E.g., if the serializable object is connected to a database table containing private information."}),"\n",(0,s.jsx)(t.p,{children:"To make a serializable class generated only on the server side, set the serverOnly property to true."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: MyPrivateClass\nserverOnly: true\nfields:\n hiddenSecretKey: String\n"})}),"\n",(0,s.jsxs)(t.p,{children:["It is also possible to set a ",(0,s.jsx)(t.code,{children:"scope"})," on a per-field basis. By default all fields are visible to both the server and the client. The available scopes are ",(0,s.jsx)(t.code,{children:"all"}),", ",(0,s.jsx)(t.code,{children:"serverOnly"}),", ",(0,s.jsx)(t.code,{children:"none"}),"."]}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"none"})," is not typically used in serverpod apps. It is intended for the serverpod framework, itself."]})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: SelectivelyHiddenClass\nfields:\n hiddenSecretKey: String, scope=serverOnly\n publicKey: String\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["Serverpod's models can easily be saved to or read from the database. You can read more about this in the ",(0,s.jsx)(t.a,{href:"database/models",children:"Database"})," section."]})}),"\n",(0,s.jsx)(t.h2,{id:"exception",children:"Exception"}),"\n",(0,s.jsxs)(t.p,{children:["The Serverpod models supports creating exceptions that can be thrown in endpoints by using the ",(0,s.jsx)(t.code,{children:"exception"})," keyword. For more in-depth description on how to work with exceptions see ",(0,s.jsx)(t.a,{href:"exceptions",children:"Error handling and exceptions"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"exception: MyException\nfields:\n message: String\n errorType: MyEnum\n"})}),"\n",(0,s.jsx)(t.h2,{id:"enum",children:"Enum"}),"\n",(0,s.jsxs)(t.p,{children:["It is easy to add custom enums with serialization support by using the ",(0,s.jsx)(t.code,{children:"enum"})," keyword."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsx)(t.p,{children:"By default the serialization will convert the enum to an int representing the index of the value. Changing the order may therefore have unforeseen consequences when reusing old data (such as from a database). Changing the serialization to be based on the name instead of index is easy."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nserialized: byName\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.code,{children:"serialized"})," has two valid values ",(0,s.jsx)(t.code,{children:"byName"})," and ",(0,s.jsx)(t.code,{children:"byIndex"}),". When using ",(0,s.jsx)(t.code,{children:"byName"})," the string literal of the enum is used, when using ",(0,s.jsx)(t.code,{children:"byIndex"})," the index value (0, 1, 2, etc) is used."]}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["It's recommended to always set ",(0,s.jsx)(t.code,{children:"serialized"})," to ",(0,s.jsx)(t.code,{children:"byName"})," in any new Enum models, as this is less fragile and will be changed to the default setting in version 3 of Serverpod."]})}),"\n",(0,s.jsx)(t.h2,{id:"adding-documentation",children:"Adding documentation"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod allows you to add documentation to your serializable objects in a similar way that you would add documentation to your Dart code. Use three hashes (###) to indicate that a comment should be considered documentation."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"### Information about a company.\nclass: Company\nfields:\n ### The name of the company.\n name: String\n\n ### The date the company was founded, if known.\n foundedDate: DateTime?\n\n ### A list of people currently employed at the company.\n employees: List\n"})}),"\n",(0,s.jsx)(t.h2,{id:"generated-code",children:"Generated code"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod generates some convenience methods on the Dart classes."}),"\n",(0,s.jsx)(t.h3,{id:"copywith",children:"copyWith"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method allows for efficient object copying with selective field updates and is available on all generated ",(0,s.jsx)(t.code,{children:"class"}),"es. Here's how it operates:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"var john = User(name: 'John Doe', age: 25);\nvar jane = john.copyWith(name: 'Jane Doe');\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method generates a deep copy of an object, preserving all original fields unless explicitly modified. It can distinguish between a field set to ",(0,s.jsx)(t.code,{children:"null"})," and a field left unspecified (undefined). When using ",(0,s.jsx)(t.code,{children:"copyWith"}),", any field you don't update remains unchanged in the new object."]}),"\n",(0,s.jsx)(t.h3,{id:"tojson--fromjson",children:"toJson / fromJson"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"toJson"})," and ",(0,s.jsx)(t.code,{children:"fromJson"})," methods are generated on all models to help with serialization. Serverpod manages all serialization for you out of the box and you will rarely have to use these methods by your self. See the ",(0,s.jsx)(t.a,{href:"serialization",children:"Serialization"})," section for more info."]}),"\n",(0,s.jsx)(t.h3,{id:"custom-methods",children:"Custom methods"}),"\n",(0,s.jsxs)(t.p,{children:["Sometimes you will want to add custom methods to the generated classes. The easiest way to do this is with ",(0,s.jsx)(t.a,{href:"https://dart.dev/language/extension-methods",children:"Dart's extension feature"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"extension MyExtension on MyClass {\n bool isCustomMethod() {\n return true;\n }\n}\n"})}),"\n",(0,s.jsx)(t.h2,{id:"default-values",children:"Default Values"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod supports defining default values for fields in your models. These default values can be specified using three different keywords that determine how and where the defaults are applied:"}),"\n",(0,s.jsx)(t.h3,{id:"keywords",children:"Keywords"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"default"}),": This keyword sets a default value for both the model (code) and the database (persisted data). It acts as a general fallback if more specific defaults aren't provided."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"defaultModel"}),": This keyword sets a default value specifically for the model (the code side). If ",(0,s.jsx)(t.code,{children:"defaultModel"})," is not provided, the model will use the value specified by ",(0,s.jsx)(t.code,{children:"default"})," if it's available."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"defaultPersist"}),": This keyword sets a default value specifically for the database. If ",(0,s.jsx)(t.code,{children:"defaultPersist"})," is not provided, the database will use the value specified by ",(0,s.jsx)(t.code,{children:"default"})," if it's available."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"how-priorities-work",children:"How priorities work"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"For the model (code side):"})," If both ",(0,s.jsx)(t.code,{children:"defaultModel"})," and ",(0,s.jsx)(t.code,{children:"default"})," are provided, the model will use the ",(0,s.jsx)(t.code,{children:"defaultModel"})," value. If ",(0,s.jsx)(t.code,{children:"defaultModel"})," is not provided, it will fall back to using the ",(0,s.jsx)(t.code,{children:"default"})," value."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"For the database (persisted data):"})," If both ",(0,s.jsx)(t.code,{children:"defaultPersist"})," and ",(0,s.jsx)(t.code,{children:"default"})," are provided, the database will use the ",(0,s.jsx)(t.code,{children:"defaultPersist"})," value. If ",(0,s.jsx)(t.code,{children:"defaultPersist"})," is not provided, it will fall back to using the ",(0,s.jsx)(t.code,{children:"default"})," value."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"You can use these default values individually or in combination as needed. It is not required to use all default types for a field."}),"\n",(0,s.jsxs)(t.admonition,{type:"info",children:[(0,s.jsxs)(t.p,{children:["When using ",(0,s.jsx)(t.code,{children:"default"})," or ",(0,s.jsx)(t.code,{children:"defaultModel"})," in combination with ",(0,s.jsx)(t.code,{children:"defaultPersist"}),", it's important to understand how the interaction between these keywords affects the final value in the database."]}),(0,s.jsxs)(t.p,{children:["If you set a ",(0,s.jsx)(t.code,{children:"default"})," or ",(0,s.jsx)(t.code,{children:"defaultModel"})," value, the model's field or variable will have a value when it's passed to the database\u2014it will not be ",(0,s.jsx)(t.code,{children:"null"}),". Because of this, the SQL query will not use the ",(0,s.jsx)(t.code,{children:"defaultPersist"})," value since the field already has a value assigned by the model. In essence, assigning a ",(0,s.jsx)(t.code,{children:"default"})," or ",(0,s.jsx)(t.code,{children:"defaultModel"})," is like directly providing a value to the field, and the database will use this provided value instead of its own default."]}),(0,s.jsxs)(t.p,{children:["This means that ",(0,s.jsx)(t.code,{children:"defaultPersist"})," only comes into play when the model does not provide a value, allowing the database to apply its own default setting."]})]}),"\n",(0,s.jsx)(t.h3,{id:"supported-default-values",children:"Supported default values"}),"\n",(0,s.jsx)(t.h4,{id:"boolean",children:"Boolean"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Boolean"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"true"})," or ",(0,s.jsx)(t.code,{children:"false"})]}),(0,s.jsxs)(t.td,{children:["Sets the field to a boolean value, either ",(0,s.jsx)(t.code,{children:"true"})," or ",(0,s.jsx)(t.code,{children:"false"}),"."]})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"boolDefault: bool, default=true\n"})}),"\n",(0,s.jsx)(t.h4,{id:"datetime",children:"DateTime"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Current Date and Time"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"now"})}),(0,s.jsx)(t.td,{children:"Sets the field to the current date and time."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Specific UTC DateTime"})}),(0,s.jsxs)(t.td,{children:["UTC DateTime string in the format ",(0,s.jsx)(t.code,{children:"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"})]}),(0,s.jsx)(t.td,{children:"Sets the field to a specific date and time."})]})]})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"dateTimeDefaultNow: DateTime, default=now\ndateTimeDefaultUtc: DateTime, default=2024-05-01T22:00:00.000Z\n"})}),"\n",(0,s.jsx)(t.h4,{id:"double",children:"Double"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Double"})}),(0,s.jsx)(t.td,{children:"Any double value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific double value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"doubleDefault: double, default=10.5\n"})}),"\n",(0,s.jsx)(t.h4,{id:"duration",children:"Duration"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Specific Duration"})}),(0,s.jsxs)(t.td,{children:["A valid duration in the format ",(0,s.jsx)(t.code,{children:"Xd Xh Xmin Xs Xms"})]}),(0,s.jsxs)(t.td,{children:["Sets the field to a specific duration value. For example, ",(0,s.jsx)(t.code,{children:"1d 2h 10min 30s 100ms"})," represents 1 day, 2 hours, 10 minutes, 30 seconds, and 100 milliseconds."]})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"durationDefault: Duration, default=1d 2h 10min 30s 100ms\n"})}),"\n",(0,s.jsx)(t.h4,{id:"enum-1",children:"Enum"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Enum"})}),(0,s.jsx)(t.td,{children:"Any valid enum value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific enum value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: ByNameEnum\nserialized: byName\nvalues:\n - byName1\n - byName2\n"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: ByIndexEnum\nserialized: byIndex\nvalues:\n - byIndex1\n - byIndex2\n"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: EnumDefault\ntable: enum_default\nfields:\n byNameEnumDefault: ByNameEnum, default=byName1\n byIndexEnumDefault: ByIndexEnum, default=byIndex1\n"})}),"\n",(0,s.jsx)(t.p,{children:"In this example:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.code,{children:"byNameEnumDefault"})," field will default to ",(0,s.jsx)(t.code,{children:"'byName1'"})," in the database."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.code,{children:"byIndexEnumDefault"})," field will default to ",(0,s.jsx)(t.code,{children:"0"})," (the index of ",(0,s.jsx)(t.code,{children:"byIndex1"}),")."]}),"\n"]}),"\n",(0,s.jsx)(t.h4,{id:"integer",children:"Integer"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Integer"})}),(0,s.jsx)(t.td,{children:"Any integer value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific integer value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"intDefault: int, default=10\n"})}),"\n",(0,s.jsx)(t.h4,{id:"string",children:"String"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"String"})}),(0,s.jsx)(t.td,{children:"Any string value"}),(0,s.jsx)(t.td,{children:"Sets the field to a specific string value."})]})})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"stringDefault: String, default='This is a string'\n"})}),"\n",(0,s.jsx)(t.h4,{id:"uuidvalue",children:"UuidValue"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Keyword"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"Random UUID"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"random"})}),(0,s.jsxs)(t.td,{children:["Generates a random UUID. On the Dart side, ",(0,s.jsx)(t.code,{children:"Uuid().v4obj()"})," is used. On the database side, ",(0,s.jsx)(t.code,{children:"gen_random_uuid()"})," is used."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.strong,{children:"UUID String"})}),(0,s.jsx)(t.td,{children:"A valid UUID version 4 string"}),(0,s.jsx)(t.td,{children:"Assigns a specific UUID to the field."})]})]})]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"uuidDefaultRandom: UuidValue, default=random\nuuidDefaultUuid: UuidValue, default='550e8400-e29b-41d4-a716-446655440000'\n"})}),"\n",(0,s.jsx)(t.h3,{id:"example",children:"Example"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:'class: DefaultValue\ntable: default_value\nfields:\n ### Sets the current date and time as the default value.\n dateTimeDefault: DateTime, default=now\n\n ### Sets the default value for a boolean field.\n boolDefault: bool, defaultModel=false, defaultPersist=true\n\n ### Sets the default value for an integer field.\n intDefault: int, defaultPersist=20\n\n ### Sets the default value for a double field.\n doubleDefault: double, default=10.5, defaultPersist=20.5\n\n ### Sets the default value for a string field.\n stringDefault: String, default="This is a string", defaultModel="This is a string"\n'})}),"\n",(0,s.jsx)(t.h2,{id:"keywords-1",children:"Keywords"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:(0,s.jsx)(t.strong,{children:"Keyword"})}),(0,s.jsx)(t.th,{children:"Note"}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#class",children:"class"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#exception",children:"exception"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#enum",children:"enum"})})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"values"})})}),(0,s.jsx)(t.td,{children:"A special key for enums with a list of all enum values."}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"serialized"})})}),(0,s.jsx)(t.td,{children:"Sets the mode enums are serialized in"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"serverOnly"})})}),(0,s.jsx)(t.td,{children:"Boolean flag if code generator only should create the code for the server."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"table"})})}),(0,s.jsx)(t.td,{children:"A name for the database table, enables generation of database code."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/migrations#opt-out-of-migrations",children:(0,s.jsx)(t.strong,{children:"managedMigration"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to opt out of the database migration system."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"fields"})})}),(0,s.jsx)(t.td,{children:"All fields in the generated class should be listed here."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"type (fields)"})})}),(0,s.jsx)(t.td,{children:"Denotes the data type for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"scope"})})}),(0,s.jsx)(t.td,{children:"Denotes the scope for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"persist"})})}),(0,s.jsxs)(t.td,{children:["A boolean flag if the data should be stored in the database or not can be negated with ",(0,s.jsx)(t.code,{children:"!persist"})]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one",children:(0,s.jsx)(t.strong,{children:"relation"})})}),(0,s.jsx)(t.td,{children:"Sets a relation between model files, requires a table name to be set."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#bidirectional-relations",children:(0,s.jsx)(t.strong,{children:"name"})})}),(0,s.jsx)(t.td,{children:"Give a name to a relation to pair them."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#with-an-id-field",children:(0,s.jsx)(t.strong,{children:"parent"})})}),(0,s.jsx)(t.td,{children:"Sets the parent table on a relation."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#custom-foreign-key-field",children:(0,s.jsx)(t.strong,{children:"field"})})}),(0,s.jsx)(t.td,{children:"A manual specified foreign key field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onUpdate"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when updating data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onDelete"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when deleting data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#optional-relation",children:(0,s.jsx)(t.strong,{children:"optional"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to make a relation optional."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"indexes"})})}),(0,s.jsx)(t.td,{children:"Create indexes on your fields / columns."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"fields (index)"})})}),(0,s.jsx)(t.td,{children:"List the fields to create the indexes on."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"type (index)"})})}),(0,s.jsx)(t.td,{children:"The type of index to create."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"unique"})})}),(0,s.jsx)(t.td,{children:"Boolean flag to make the entries unique in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#default-values",children:(0,s.jsx)(t.strong,{children:"default"})})}),(0,s.jsxs)(t.td,{children:["Sets the default value for both the model and the database. This keyword cannot be used with ",(0,s.jsx)(t.strong,{children:"relation"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#default-values",children:(0,s.jsx)(t.strong,{children:"defaultModel"})})}),(0,s.jsxs)(t.td,{children:["Sets the default value for the model side. This keyword cannot be used with ",(0,s.jsx)(t.strong,{children:"relation"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#default-values",children:(0,s.jsx)(t.strong,{children:"defaultPersist"})})}),(0,s.jsxs)(t.td,{children:["Sets the default value for the database side. This keyword cannot be used with ",(0,s.jsx)(t.strong,{children:"relation"})," and ",(0,s.jsx)(t.strong,{children:"!persist"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,d.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(o,{...e})}):o(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var s=n(96540);const d={},l=s.createContext(d);function i(e){const t=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:i(e.components),s.createElement(l.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/441fd5fc.c6c289b1.js b/docs/assets/js/441fd5fc.fa9f8a31.js similarity index 99% rename from docs/assets/js/441fd5fc.c6c289b1.js rename to docs/assets/js/441fd5fc.fa9f8a31.js index c78cd4fa6..7d8dbd823 100644 --- a/docs/assets/js/441fd5fc.c6c289b1.js +++ b/docs/assets/js/441fd5fc.fa9f8a31.js @@ -1 +1 @@ -"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[37990],{87360:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>o});var s=n(74848),i=n(28453);const r={},d="Working with models",l={id:"concepts/models",title:"Working with models",description:'Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular .yaml files within lib/src/models is supported, but it is recommended to use .spy.yaml (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the Serverpod Extension for VS Code.',source:"@site/versioned_docs/version-2.0.0/05-concepts/02-models.md",sourceDirName:"05-concepts",slug:"/concepts/models",permalink:"/2.0.0/concepts/models",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/versioned_docs/version-2.0.0/05-concepts/02-models.md",tags:[],version:"2.0.0",sidebarPosition:2,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Working with endpoints",permalink:"/2.0.0/concepts/working-with-endpoints"},next:{title:"Custom serialization",permalink:"/2.0.0/concepts/serialization"}},a={},o=[{value:"Class",id:"class",level:2},{value:"Limiting visibility of a generated class",id:"limiting-visibility-of-a-generated-class",level:3},{value:"Exception",id:"exception",level:2},{value:"Enum",id:"enum",level:2},{value:"Adding documentation",id:"adding-documentation",level:2},{value:"Generated code",id:"generated-code",level:2},{value:"copyWith",id:"copywith",level:3},{value:"toJson / fromJson",id:"tojson--fromjson",level:3},{value:"Custom methods",id:"custom-methods",level:3},{value:"Keywords",id:"keywords",level:2}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"working-with-models",children:"Working with models"})}),"\n",(0,s.jsxs)(t.p,{children:["Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular ",(0,s.jsx)(t.code,{children:".yaml"})," files within ",(0,s.jsx)(t.code,{children:"lib/src/models"})," is supported, but it is recommended to use ",(0,s.jsx)(t.code,{children:".spy.yaml"}),' (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the ',(0,s.jsx)(t.a,{href:"https://marketplace.visualstudio.com/items?itemName=serverpod.serverpod",children:"Serverpod Extension"})," for VS Code."]}),"\n",(0,s.jsx)(t.p,{children:"The files are analyzed by the Serverpod CLI when generating the project and creating migrations."}),"\n",(0,s.jsxs)(t.p,{children:["Run ",(0,s.jsx)(t.code,{children:"serverpod generate"})," to generate dart classes from the model files."]}),"\n",(0,s.jsx)(t.h2,{id:"class",children:"Class"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: Company\nfields:\n name: String\n foundedDate: DateTime?\n employees: List\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Supported types are ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/bool-class.html",children:"bool"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/int-class.html",children:"int"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/double-class.html",children:"double"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/String-class.html",children:"String"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Duration-class.html",children:"Duration"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/DateTime-class.html",children:"DateTime"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-typed_data/ByteData-class.html",children:"ByteData"}),", ",(0,s.jsx)(t.a,{href:"https://pub.dev/documentation/uuid/latest/uuid_value/UuidValue-class.html",children:"UuidValue"}),", and other serializable ",(0,s.jsx)(t.a,{href:"#class",children:"classes"}),", ",(0,s.jsx)(t.a,{href:"#exception",children:"exceptions"})," and ",(0,s.jsx)(t.a,{href:"#enum",children:"enums"}),". You can also use ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/List-class.html",children:"List"}),"s and ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Map-class.html",children:"Map"}),"s of the supported types, just make sure to specify the types. Null safety is supported. Once your classes are generated, you can use them as parameters or return types to endpoint methods."]}),"\n",(0,s.jsx)(t.h3,{id:"limiting-visibility-of-a-generated-class",children:"Limiting visibility of a generated class"}),"\n",(0,s.jsx)(t.p,{children:"By default, generated code for your serializable objects is available both on the server and the client. You may want to have the code on the server side only. E.g., if the serializable object is connected to a database table containing private information."}),"\n",(0,s.jsx)(t.p,{children:"To make a serializable class generated only on the server side, set the serverOnly property to true."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: MyPrivateClass\nserverOnly: true\nfields:\n hiddenSecretKey: String\n"})}),"\n",(0,s.jsxs)(t.p,{children:["It is also possible to set a ",(0,s.jsx)(t.code,{children:"scope"})," on a per-field basis. By default all fields are visible to both the server and the client. The available scopes are ",(0,s.jsx)(t.code,{children:"all"}),", ",(0,s.jsx)(t.code,{children:"serverOnly"}),", ",(0,s.jsx)(t.code,{children:"none"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: SelectivelyHiddenClass\nfields:\n hiddenSecretKey: String, scope=serverOnly\n publicKey: String\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["Serverpod's models can easily be saved to or read from the database. You can read more about this in the ",(0,s.jsx)(t.a,{href:"database/models",children:"Database"})," section."]})}),"\n",(0,s.jsx)(t.h2,{id:"exception",children:"Exception"}),"\n",(0,s.jsxs)(t.p,{children:["The Serverpod models supports creating exceptions that can be thrown in endpoints by using the ",(0,s.jsx)(t.code,{children:"exception"})," keyword. For more in-depth description on how to work with exceptions see ",(0,s.jsx)(t.a,{href:"exceptions",children:"Error handling and exceptions"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"exception: MyException\nfields:\n message: String\n errorType: MyEnum\n"})}),"\n",(0,s.jsx)(t.h2,{id:"enum",children:"Enum"}),"\n",(0,s.jsxs)(t.p,{children:["It is easy to add custom enums with serialization support by using the ",(0,s.jsx)(t.code,{children:"enum"})," keyword."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsx)(t.p,{children:"By default the serialization will convert the enum to an int representing the index of the value. Changing the order may therefore have unforeseen consequences when reusing old data (such as from a database). Changing the serialization to be based on the name instead of index is easy."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nserialized: byName\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.code,{children:"serialized"})," has two valid values ",(0,s.jsx)(t.code,{children:"byName"})," and ",(0,s.jsx)(t.code,{children:"byIndex"}),". When using ",(0,s.jsx)(t.code,{children:"byName"})," the string literal of the enum is used, when using ",(0,s.jsx)(t.code,{children:"byIndex"})," the index value (0, 1, 2, etc) is used."]}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["It's recommended to always set ",(0,s.jsx)(t.code,{children:"serialized"})," to ",(0,s.jsx)(t.code,{children:"byName"})," in any new Enum models, as this is less fragile and will be changed to the default setting in version 2 of Serverpod."]})}),"\n",(0,s.jsx)(t.h2,{id:"adding-documentation",children:"Adding documentation"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod allows you to add documentation to your serializable objects in a similar way that you would add documentation to your Dart code. Use three hashes (###) to indicate that a comment should be considered documentation."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"### Information about a company.\nclass: Company\nfields:\n ### The name of the company.\n name: String\n\n ### The date the company was founded, if known.\n foundedDate: DateTime?\n\n ### A list of people currently employed at the company.\n employees: List\n"})}),"\n",(0,s.jsx)(t.h2,{id:"generated-code",children:"Generated code"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod generates some convenience methods on the Dart classes."}),"\n",(0,s.jsx)(t.h3,{id:"copywith",children:"copyWith"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method allows for efficient object copying with selective field updates and is available on all generated ",(0,s.jsx)(t.code,{children:"class"}),"es. Here's how it operates:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"var john = User(name: 'John Doe', age: 25);\nvar jane = john.copyWith(name: 'Jane Doe');\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method generates a deep copy of an object, preserving all original fields unless explicitly modified. It can distinguish between a field set to ",(0,s.jsx)(t.code,{children:"null"})," and a field left unspecified (undefined). When using ",(0,s.jsx)(t.code,{children:"copyWith"}),", any field you don't update remains unchanged in the new object."]}),"\n",(0,s.jsx)(t.h3,{id:"tojson--fromjson",children:"toJson / fromJson"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"toJson"})," and ",(0,s.jsx)(t.code,{children:"fromJson"})," methods are generated on all models to help with serialization. Serverpod manages all serialization for you out of the box and you will rarely have to use these methods by your self. See the ",(0,s.jsx)(t.a,{href:"serialization",children:"Serialization"})," section for more info."]}),"\n",(0,s.jsx)(t.h3,{id:"custom-methods",children:"Custom methods"}),"\n",(0,s.jsxs)(t.p,{children:["Sometimes you will want to add custom methods to the generated classes. The easiest way to do this is with ",(0,s.jsx)(t.a,{href:"https://dart.dev/language/extension-methods",children:"Dart's extension feature"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"extension MyExtension on MyClass {\n bool isCustomMethod() {\n return true;\n }\n}\n"})}),"\n",(0,s.jsx)(t.h2,{id:"keywords",children:"Keywords"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:(0,s.jsx)(t.strong,{children:"Keyword"})}),(0,s.jsx)(t.th,{children:"Note"}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#class",children:"class"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#exception",children:"exception"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#enum",children:"enum"})})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"values"})})}),(0,s.jsx)(t.td,{children:"A special key for enums with a list of all enum values."}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"serialized"})})}),(0,s.jsx)(t.td,{children:"Sets the mode enums are serialized in"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"serverOnly"})})}),(0,s.jsx)(t.td,{children:"Boolean flag if code generator only should create the code for the server."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"table"})})}),(0,s.jsx)(t.td,{children:"A name for the database table, enables generation of database code."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/migrations#opt-out-of-migrations",children:(0,s.jsx)(t.strong,{children:"managedMigration"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to opt out of the database migration system."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"fields"})})}),(0,s.jsx)(t.td,{children:"All fields in the generated class should be listed here."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"type (fields)"})})}),(0,s.jsx)(t.td,{children:"Denotes the data type for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"scope"})})}),(0,s.jsx)(t.td,{children:"Denotes the scope for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"persist"})})}),(0,s.jsxs)(t.td,{children:["A boolean flag if the data should be stored in the database or not can be negated with ",(0,s.jsx)(t.code,{children:"!persist"})]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one",children:(0,s.jsx)(t.strong,{children:"relation"})})}),(0,s.jsx)(t.td,{children:"Sets a relation between model files, requires a table name to be set."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#bidirectional-relations",children:(0,s.jsx)(t.strong,{children:"name"})})}),(0,s.jsx)(t.td,{children:"Give a name to a relation to pair them."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#with-an-id-field",children:(0,s.jsx)(t.strong,{children:"parent"})})}),(0,s.jsx)(t.td,{children:"Sets the parent table on a relation."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#custom-foreign-key-field",children:(0,s.jsx)(t.strong,{children:"field"})})}),(0,s.jsx)(t.td,{children:"A manual specified foreign key field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onUpdate"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when updating data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onDelete"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when deleting data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#optional-relation",children:(0,s.jsx)(t.strong,{children:"optional"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to make a relation optional."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"indexes"})})}),(0,s.jsx)(t.td,{children:"Create indexes on your fields / columns."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"fields (index)"})})}),(0,s.jsx)(t.td,{children:"List the fields to create the indexes on."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"type (index)"})})}),(0,s.jsx)(t.td,{children:"The type of index to create."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"unique"})})}),(0,s.jsx)(t.td,{children:"Boolean flag to make the entries unique in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>d,x:()=>l});var s=n(96540);const i={},r=s.createContext(i);function d(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[37990],{87360:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>o});var s=n(74848),i=n(28453);const r={},d="Working with models",l={id:"concepts/models",title:"Working with models",description:'Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular .yaml files within lib/src/models is supported, but it is recommended to use .spy.yaml (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the Serverpod Extension for VS Code.',source:"@site/versioned_docs/version-2.0.0/05-concepts/02-models.md",sourceDirName:"05-concepts",slug:"/concepts/models",permalink:"/2.0.0/concepts/models",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/versioned_docs/version-2.0.0/05-concepts/02-models.md",tags:[],version:"2.0.0",sidebarPosition:2,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Working with endpoints",permalink:"/2.0.0/concepts/working-with-endpoints"},next:{title:"Custom serialization",permalink:"/2.0.0/concepts/serialization"}},a={},o=[{value:"Class",id:"class",level:2},{value:"Limiting visibility of a generated class",id:"limiting-visibility-of-a-generated-class",level:3},{value:"Exception",id:"exception",level:2},{value:"Enum",id:"enum",level:2},{value:"Adding documentation",id:"adding-documentation",level:2},{value:"Generated code",id:"generated-code",level:2},{value:"copyWith",id:"copywith",level:3},{value:"toJson / fromJson",id:"tojson--fromjson",level:3},{value:"Custom methods",id:"custom-methods",level:3},{value:"Keywords",id:"keywords",level:2}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"working-with-models",children:"Working with models"})}),"\n",(0,s.jsxs)(t.p,{children:["Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular ",(0,s.jsx)(t.code,{children:".yaml"})," files within ",(0,s.jsx)(t.code,{children:"lib/src/models"})," is supported, but it is recommended to use ",(0,s.jsx)(t.code,{children:".spy.yaml"}),' (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the ',(0,s.jsx)(t.a,{href:"https://marketplace.visualstudio.com/items?itemName=serverpod.serverpod",children:"Serverpod Extension"})," for VS Code."]}),"\n",(0,s.jsx)(t.p,{children:"The files are analyzed by the Serverpod CLI when generating the project and creating migrations."}),"\n",(0,s.jsxs)(t.p,{children:["Run ",(0,s.jsx)(t.code,{children:"serverpod generate"})," to generate dart classes from the model files."]}),"\n",(0,s.jsx)(t.h2,{id:"class",children:"Class"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: Company\nfields:\n name: String\n foundedDate: DateTime?\n employees: List\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Supported types are ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/bool-class.html",children:"bool"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/int-class.html",children:"int"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/double-class.html",children:"double"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/String-class.html",children:"String"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Duration-class.html",children:"Duration"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/DateTime-class.html",children:"DateTime"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-typed_data/ByteData-class.html",children:"ByteData"}),", ",(0,s.jsx)(t.a,{href:"https://pub.dev/documentation/uuid/latest/uuid_value/UuidValue-class.html",children:"UuidValue"}),", and other serializable ",(0,s.jsx)(t.a,{href:"#class",children:"classes"}),", ",(0,s.jsx)(t.a,{href:"#exception",children:"exceptions"})," and ",(0,s.jsx)(t.a,{href:"#enum",children:"enums"}),". You can also use ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/List-class.html",children:"List"}),"s and ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Map-class.html",children:"Map"}),"s of the supported types, just make sure to specify the types. Null safety is supported. Once your classes are generated, you can use them as parameters or return types to endpoint methods."]}),"\n",(0,s.jsx)(t.h3,{id:"limiting-visibility-of-a-generated-class",children:"Limiting visibility of a generated class"}),"\n",(0,s.jsx)(t.p,{children:"By default, generated code for your serializable objects is available both on the server and the client. You may want to have the code on the server side only. E.g., if the serializable object is connected to a database table containing private information."}),"\n",(0,s.jsx)(t.p,{children:"To make a serializable class generated only on the server side, set the serverOnly property to true."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: MyPrivateClass\nserverOnly: true\nfields:\n hiddenSecretKey: String\n"})}),"\n",(0,s.jsxs)(t.p,{children:["It is also possible to set a ",(0,s.jsx)(t.code,{children:"scope"})," on a per-field basis. By default all fields are visible to both the server and the client. The available scopes are ",(0,s.jsx)(t.code,{children:"all"}),", ",(0,s.jsx)(t.code,{children:"serverOnly"}),", ",(0,s.jsx)(t.code,{children:"none"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: SelectivelyHiddenClass\nfields:\n hiddenSecretKey: String, scope=serverOnly\n publicKey: String\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["Serverpod's models can easily be saved to or read from the database. You can read more about this in the ",(0,s.jsx)(t.a,{href:"database/models",children:"Database"})," section."]})}),"\n",(0,s.jsx)(t.h2,{id:"exception",children:"Exception"}),"\n",(0,s.jsxs)(t.p,{children:["The Serverpod models supports creating exceptions that can be thrown in endpoints by using the ",(0,s.jsx)(t.code,{children:"exception"})," keyword. For more in-depth description on how to work with exceptions see ",(0,s.jsx)(t.a,{href:"exceptions",children:"Error handling and exceptions"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"exception: MyException\nfields:\n message: String\n errorType: MyEnum\n"})}),"\n",(0,s.jsx)(t.h2,{id:"enum",children:"Enum"}),"\n",(0,s.jsxs)(t.p,{children:["It is easy to add custom enums with serialization support by using the ",(0,s.jsx)(t.code,{children:"enum"})," keyword."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsx)(t.p,{children:"By default the serialization will convert the enum to an int representing the index of the value. Changing the order may therefore have unforeseen consequences when reusing old data (such as from a database). Changing the serialization to be based on the name instead of index is easy."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nserialized: byName\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.code,{children:"serialized"})," has two valid values ",(0,s.jsx)(t.code,{children:"byName"})," and ",(0,s.jsx)(t.code,{children:"byIndex"}),". When using ",(0,s.jsx)(t.code,{children:"byName"})," the string literal of the enum is used, when using ",(0,s.jsx)(t.code,{children:"byIndex"})," the index value (0, 1, 2, etc) is used."]}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["It's recommended to always set ",(0,s.jsx)(t.code,{children:"serialized"})," to ",(0,s.jsx)(t.code,{children:"byName"})," in any new Enum models, as this is less fragile and will be changed to the default setting in version 3 of Serverpod."]})}),"\n",(0,s.jsx)(t.h2,{id:"adding-documentation",children:"Adding documentation"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod allows you to add documentation to your serializable objects in a similar way that you would add documentation to your Dart code. Use three hashes (###) to indicate that a comment should be considered documentation."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"### Information about a company.\nclass: Company\nfields:\n ### The name of the company.\n name: String\n\n ### The date the company was founded, if known.\n foundedDate: DateTime?\n\n ### A list of people currently employed at the company.\n employees: List\n"})}),"\n",(0,s.jsx)(t.h2,{id:"generated-code",children:"Generated code"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod generates some convenience methods on the Dart classes."}),"\n",(0,s.jsx)(t.h3,{id:"copywith",children:"copyWith"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method allows for efficient object copying with selective field updates and is available on all generated ",(0,s.jsx)(t.code,{children:"class"}),"es. Here's how it operates:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"var john = User(name: 'John Doe', age: 25);\nvar jane = john.copyWith(name: 'Jane Doe');\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method generates a deep copy of an object, preserving all original fields unless explicitly modified. It can distinguish between a field set to ",(0,s.jsx)(t.code,{children:"null"})," and a field left unspecified (undefined). When using ",(0,s.jsx)(t.code,{children:"copyWith"}),", any field you don't update remains unchanged in the new object."]}),"\n",(0,s.jsx)(t.h3,{id:"tojson--fromjson",children:"toJson / fromJson"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"toJson"})," and ",(0,s.jsx)(t.code,{children:"fromJson"})," methods are generated on all models to help with serialization. Serverpod manages all serialization for you out of the box and you will rarely have to use these methods by your self. See the ",(0,s.jsx)(t.a,{href:"serialization",children:"Serialization"})," section for more info."]}),"\n",(0,s.jsx)(t.h3,{id:"custom-methods",children:"Custom methods"}),"\n",(0,s.jsxs)(t.p,{children:["Sometimes you will want to add custom methods to the generated classes. The easiest way to do this is with ",(0,s.jsx)(t.a,{href:"https://dart.dev/language/extension-methods",children:"Dart's extension feature"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"extension MyExtension on MyClass {\n bool isCustomMethod() {\n return true;\n }\n}\n"})}),"\n",(0,s.jsx)(t.h2,{id:"keywords",children:"Keywords"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:(0,s.jsx)(t.strong,{children:"Keyword"})}),(0,s.jsx)(t.th,{children:"Note"}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#class",children:"class"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#exception",children:"exception"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#enum",children:"enum"})})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"values"})})}),(0,s.jsx)(t.td,{children:"A special key for enums with a list of all enum values."}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"serialized"})})}),(0,s.jsx)(t.td,{children:"Sets the mode enums are serialized in"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"serverOnly"})})}),(0,s.jsx)(t.td,{children:"Boolean flag if code generator only should create the code for the server."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"table"})})}),(0,s.jsx)(t.td,{children:"A name for the database table, enables generation of database code."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/migrations#opt-out-of-migrations",children:(0,s.jsx)(t.strong,{children:"managedMigration"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to opt out of the database migration system."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"fields"})})}),(0,s.jsx)(t.td,{children:"All fields in the generated class should be listed here."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"type (fields)"})})}),(0,s.jsx)(t.td,{children:"Denotes the data type for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"scope"})})}),(0,s.jsx)(t.td,{children:"Denotes the scope for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"persist"})})}),(0,s.jsxs)(t.td,{children:["A boolean flag if the data should be stored in the database or not can be negated with ",(0,s.jsx)(t.code,{children:"!persist"})]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one",children:(0,s.jsx)(t.strong,{children:"relation"})})}),(0,s.jsx)(t.td,{children:"Sets a relation between model files, requires a table name to be set."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#bidirectional-relations",children:(0,s.jsx)(t.strong,{children:"name"})})}),(0,s.jsx)(t.td,{children:"Give a name to a relation to pair them."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#with-an-id-field",children:(0,s.jsx)(t.strong,{children:"parent"})})}),(0,s.jsx)(t.td,{children:"Sets the parent table on a relation."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#custom-foreign-key-field",children:(0,s.jsx)(t.strong,{children:"field"})})}),(0,s.jsx)(t.td,{children:"A manual specified foreign key field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onUpdate"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when updating data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onDelete"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when deleting data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#optional-relation",children:(0,s.jsx)(t.strong,{children:"optional"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to make a relation optional."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"indexes"})})}),(0,s.jsx)(t.td,{children:"Create indexes on your fields / columns."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"fields (index)"})})}),(0,s.jsx)(t.td,{children:"List the fields to create the indexes on."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"type (index)"})})}),(0,s.jsx)(t.td,{children:"The type of index to create."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"unique"})})}),(0,s.jsx)(t.td,{children:"Boolean flag to make the entries unique in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>d,x:()=>l});var s=n(96540);const i={},r=s.createContext(i);function d(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/7ac69e68.07813519.js b/docs/assets/js/7ac69e68.e3dc9e21.js similarity index 93% rename from docs/assets/js/7ac69e68.07813519.js rename to docs/assets/js/7ac69e68.e3dc9e21.js index 1a0c1d73a..3c5102a87 100644 --- a/docs/assets/js/7ac69e68.07813519.js +++ b/docs/assets/js/7ac69e68.e3dc9e21.js @@ -1 +1 @@ -"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[27168],{65650:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>l});var a=t(74848),i=t(28453);const s={},r="Upgrade to 2.0",o={id:"upgrading/upgrade-to-two",title:"Upgrade to 2.0",description:"Changes to authentication",source:"@site/versioned_docs/version-2.0.0/12-upgrading/01-upgrade-to-two.md",sourceDirName:"12-upgrading",slug:"/upgrading/upgrade-to-two",permalink:"/2.0.0/upgrading/upgrade-to-two",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/versioned_docs/version-2.0.0/12-upgrading/01-upgrade-to-two.md",tags:[],version:"2.0.0",sidebarPosition:1,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Contribute",permalink:"/2.0.0/contribute"},next:{title:"Upgrade to 1.2",permalink:"/2.0.0/upgrading/upgrade-to-one-point-two"}},d={},l=[{value:"Changes to authentication",id:"changes-to-authentication",level:2},{value:"Advanced integrations",id:"advanced-integrations",level:3},{value:"Changes to the Session Object",id:"changes-to-the-session-object",level:2},{value:"Removed deprecated fields",id:"removed-deprecated-fields",level:3},{value:"Authenticated user information retrieval",id:"authenticated-user-information-retrieval",level:3},{value:"Authentication helpers",id:"authentication-helpers",level:3},{value:"Changes to database queries",id:"changes-to-database-queries",level:2},{value:"Removed unsafeQueryMappedResults(...)",id:"removed-unsafequerymappedresults",level:3},{value:"Update return type for delete operations",id:"update-return-type-for-delete-operations",level:3},{value:"Changes to database tables",id:"changes-to-database-tables",level:2},{value:"Integer representation changed to bigint",id:"integer-representation-changed-to-bigint",level:3},{value:"Why is this change made?",id:"why-is-this-change-made",level:4},{value:"Ensuring new databases are created with the new representation",id:"ensuring-new-databases-are-created-with-the-new-representation",level:4},{value:"Migration of existing tables",id:"migration-of-existing-tables",level:4},{value:"Small tables",id:"small-tables",level:5},{value:"Large tables",id:"large-tables",level:5},{value:"Changes in the authentication module",id:"changes-in-the-authentication-module",level:2},{value:"Unsecure random disabled by default",id:"unsecure-random-disabled-by-default",level:3},{value:"Updates to Serialization in Serverpod 2.0",id:"updates-to-serialization-in-serverpod-20",level:2},{value:"General Changes to Model Serialization",id:"general-changes-to-model-serialization",level:3},{value:"Before change",id:"before-change",level:4},{value:"After change",id:"after-change",level:4},{value:"Enhancements for Custom Serialization",id:"enhancements-for-custom-serialization",level:3},{value:"Previous Implementation",id:"previous-implementation",level:4},{value:"Updated Implementation",id:"updated-implementation",level:4},{value:"Deprecation Notice for SerializableEntity",id:"deprecation-notice-for-serializableentity",level:2},{value:"Migration Guide",id:"migration-guide",level:3},{value:"Example",id:"example",level:4}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"upgrade-to-20",children:"Upgrade to 2.0"})}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-authentication",children:"Changes to authentication"}),"\n",(0,a.jsxs)(n.p,{children:["The base auth implementation has been removed from Serverpod core and moved into the ",(0,a.jsx)(n.code,{children:"serverpod_auth"})," package. If you are not using authentication at all this change does not impact you. If you are using the auth module already the transition is simple."]}),"\n",(0,a.jsxs)(n.p,{children:["The default authentication handler will now throw an ",(0,a.jsx)(n.code,{children:"UnimplementedError"}),". It is now required to supply the authentication handler to the Serverpod object, in your server.dart file make the following change:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"import 'package:serverpod_auth_server/serverpod_auth_server.dart' as auth;\n\nvoid run(List args) async {\n var pod = Serverpod(\n args,\n Protocol(),\n Endpoints(),\n authenticationHandler: auth.authenticationHandler, // Add this line\n );\n\n ...\n}\n"})}),"\n",(0,a.jsx)(n.h3,{id:"advanced-integrations",children:"Advanced integrations"}),"\n",(0,a.jsxs)(n.p,{children:["The methods ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," now takes the session object as a param and is no longer available on the session object. Instead import the class ",(0,a.jsx)(n.code,{children:"UserAuthentication"})," from the auth module to access these static methods."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"UserAuthentication.signInUser(session, userId, 'provider');\n\nUserAuthentication.signOutUser(session);\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The table ",(0,a.jsx)(n.code,{children:"serverpod_auth_key"})," has been removed from Serverpod core but is available in the serverpod_auth module instead. This means that if you wrote a custom integration before without using the serverpod_auth module you have to take care of managing your token implementation."]}),"\n",(0,a.jsxs)(n.p,{children:["Adding the definition of the ",(0,a.jsx)(n.code,{children:"serverpod_auth_key"})," table to your project is the simplest way to do a seamless migration."]}),"\n",(0,a.jsx)(n.p,{children:"The table was defined in the following way:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"### Provides a method of access for a user to authenticate with the server.\nclass: AuthKey\ntable: serverpod_auth_key\nfields:\n ### The id of the user to provide access to.\n userId: int\n\n ### The hashed version of the key.\n hash: String\n\n ### The key sent to the server to authenticate.\n key: String?, !persist\n\n ### The scopes this key provides access to.\n scopeNames: List\n\n ### The method of signing in this key was generated through. This can be email\n ### or different social logins.\n method: String\nindexes:\n serverpod_auth_key_userId_idx:\n fields: userId\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Your are then responsible for creating/removing entries in this table, the old ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," that used to provide this functionality can be found ",(0,a.jsx)(n.a,{href:"https://github.com/serverpod/serverpod/blob/13795a7bd4c0cc5a03101b6f378cb914673046dd/packages/serverpod/lib/src/server/session.dart#L359-L394",children:"here"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-the-session-object",children:"Changes to the Session Object"}),"\n",(0,a.jsx)(n.h3,{id:"removed-deprecated-fields",children:"Removed deprecated fields"}),"\n",(0,a.jsxs)(n.p,{children:["With Serverpod 2.0, we have removed the deprecated legacy database layer from the ",(0,a.jsx)(n.code,{children:"Session"})," object. The ",(0,a.jsx)(n.code,{children:"Session"})," object now incorporates the new database layer, accessed via the ",(0,a.jsx)(n.code,{children:"dbNext"})," field in Serverpod 1.2, under the ",(0,a.jsx)(n.code,{children:"db"})," field."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"session.dbNext.find(...);\n"})}),"\n",(0,a.jsx)(n.p,{children:"becomes"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"session.db.find(...);\n"})}),"\n",(0,a.jsx)(n.h3,{id:"authenticated-user-information-retrieval",children:"Authenticated user information retrieval"}),"\n",(0,a.jsxs)(n.p,{children:["In Serverpod 2.0, we have removed the getters ",(0,a.jsx)(n.code,{children:"scopes"})," and ",(0,a.jsx)(n.code,{children:"authenticatedUser"})," from session. This information is now retrievable through the ",(0,a.jsx)(n.code,{children:"authenticated"})," getter as fields of the returned object."]}),"\n",(0,a.jsx)(n.p,{children:"Replace this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"int? userId = await session.auth.authenticatedUser;\n\nSet? scopes = await session.scopes;\n"})}),"\n",(0,a.jsx)(n.p,{children:"With this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final authenticated = await session.authenticated;\n\n//Read authenticated userId\nint? userId = authenticated?.userId;\n\n//Read scopes\nSet? scopes = authenticated?.scopes;\n"})}),"\n",(0,a.jsxs)(n.p,{children:["If the ",(0,a.jsx)(n.code,{children:"authenticated"})," property is set on the session it effectively means there is an authenticated user making the request."]}),"\n",(0,a.jsx)(n.h3,{id:"authentication-helpers",children:"Authentication helpers"}),"\n",(0,a.jsxs)(n.p,{children:["The field ",(0,a.jsx)(n.code,{children:"auth"})," has been removed and the methods ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," have been moved to the ",(0,a.jsx)(n.code,{children:"serverpod_auth"})," module."]}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-database-queries",children:"Changes to database queries"}),"\n",(0,a.jsx)(n.h3,{id:"removed-unsafequerymappedresults",children:"Removed unsafeQueryMappedResults(...)"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," method has been removed. A similar result can now instead be formatted from the ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," result by calling the ",(0,a.jsx)(n.code,{children:"toColumnMap()"})," method for each row of the result. ",(0,a.jsx)(n.code,{children:"toColumnMap"})," returns a map containing the query alias for the column as key and the row-column value as value."]}),"\n",(0,a.jsx)(n.p,{children:"Given a query that performs a join like this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'SELECT\n "company"."id" AS "company.id",\n "company"."name" AS "company.name",\n "company"."townId" AS "company.townId",\n "company_town_town"."id" AS "company_town_town.id",\n "company_town_town"."name" AS "company_town_town.name",\n "company_town_town"."mayorId" AS "company_town_town.mayorId"\nFROM\n "company"\nLEFT JOIN\n "town" AS "company_town_town" ON "company"."townId" = "company_town_town"."id"\nORDER BY\n "company"."name"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The return type from ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," in 1.2 was:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company": {\n "company.id": 40,\n "company.name": "Apple",\n "company.townId": 64\n },\n "town": {\n "company_town_town.id": 64,\n "company_town_town.name": "San Francisco",\n "company_town_town.mayorId": null\n }\n },\n {\n "company": {\n "company.id": 39,\n "company.name": "Serverpod",\n "company.townId": 63\n },\n "town": {\n "company_town_town.id": 63,\n "company_town_town.name": "Stockholm",\n "company_town_town.mayorId": null\n }\n }\n]\n'})}),"\n",(0,a.jsxs)(n.p,{children:["And if ",(0,a.jsx)(n.code,{children:"result.map((row) => row.toColumnMap())"})," is used to format the result from ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," in 2.0, the following result is obtained:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company.id": 38,\n "company.name": "Apple",\n "company.townId": 62,\n "company_town_town.id": 62,\n "company_town_town.name": "San Francisco",\n "company_town_town.mayorId": null\n },\n {\n "company.id": 37,\n "company.name": "Serverpod",\n "company.townId": 61,\n "company_town_town.id": 61,\n "company_town_town.name": "Stockholm",\n "company_town_town.mayorId": null\n }\n]\n'})}),"\n",(0,a.jsx)(n.p,{children:"or for a simple query without aliases:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'SELECT\n "id",\n "name",\n "townId"\nFROM\n "company"\nORDER BY\n "name"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["the return type from ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," in 1.2 was:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company": {\n "id": 54,\n "name": "Apple",\n "townId": 86\n }\n },\n {\n "company": {\n "id": 53,\n "name": "Serverpod",\n "townId": 85\n }\n }\n]\n'})}),"\n",(0,a.jsxs)(n.p,{children:["and if ",(0,a.jsx)(n.code,{children:"result.map((row) => row.toColumnMap())"})," is used to format the result from ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," in 2.0, the following result is obtained:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:' [\n {\n "id": 54,\n "name": "Apple",\n "townId": 86\n },\n {\n "id": 53,\n "name": "Serverpod",\n "townId": 85\n }\n]\n'})}),"\n",(0,a.jsx)(n.h3,{id:"update-return-type-for-delete-operations",children:"Update return type for delete operations"}),"\n",(0,a.jsxs)(n.p,{children:["The return type for all delete operations has been changed from the ",(0,a.jsx)(n.code,{children:"id"})," of the deleted rows to the actual deleted rows. This makes the return type for the delete operations consistent with the return type of the other database operations. It also dramatically simplifies retrieving and removing rows in concurrent environments."]}),"\n",(0,a.jsx)(n.p,{children:"Return type before the change:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"int companyId = await Company.db.deleteRow(session, company);\nList companyIds = await Company.db.delete(session, [company]);\nList companyIds = await Company.db.deleteWhere(session, where: (t) => t.name.like('%Ltd'));\n"})}),"\n",(0,a.jsx)(n.p,{children:"Return types after the change:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"Company company = await Company.db.deleteRow(session, company);\nList companies = await Company.db.delete(session, [company]);\nList companies = await Company.db.deleteWhere(session, where: (t) => t.name.like('%Ltd'));\n"})}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-database-tables",children:"Changes to database tables"}),"\n",(0,a.jsx)(n.h3,{id:"integer-representation-changed-to-bigint",children:"Integer representation changed to bigint"}),"\n",(0,a.jsxs)(n.p,{children:["Integer representation in the database has changed from ",(0,a.jsx)(n.code,{children:"int"})," to ",(0,a.jsx)(n.code,{children:"bigint"}),". From now on, models with ",(0,a.jsx)(n.code,{children:"int"})," fields will generate database migrations where that field is defined as a ",(0,a.jsx)(n.code,{children:"bigint"})," type in the database."]}),"\n",(0,a.jsxs)(n.p,{children:["This change also applies to the ",(0,a.jsx)(n.code,{children:"id"})," field of models where ",(0,a.jsx)(n.code,{children:"bigserial"})," is now used to generate the id."]}),"\n",(0,a.jsx)(n.p,{children:"The change is compatible with existing databases. Existing migrations therefore, won't be changed by the Serverpod migration system. No manual modification to the database is required if this data representation is not essential for the application. However, all new migrations will be created with the new representation."}),"\n",(0,a.jsx)(n.h4,{id:"why-is-this-change-made",children:"Why is this change made?"}),"\n",(0,a.jsxs)(n.p,{children:["The change was made to ensure that ",(0,a.jsx)(n.a,{href:"https://dart.dev/guides/language/numbers",children:"Dart"})," and the database representation of integers is consistent. Dart uses 64-bit integers, and the ",(0,a.jsx)(n.code,{children:"int"})," type in Dart is a 64-bit integer. The ",(0,a.jsx)(n.code,{children:"int"})," type in PostgreSQL is a 32-bit integer. This means that the ",(0,a.jsx)(n.code,{children:"int"})," type in Dart can represent larger numbers than the ",(0,a.jsx)(n.code,{children:"int"})," type in PostgreSQL. By using ",(0,a.jsx)(n.code,{children:"bigint"})," in PostgreSQL, the integer representation is consistent between Dart and the database."]}),"\n",(0,a.jsxs)(n.p,{children:["In terms of performance, there are usually no significant drawbacks with using ",(0,a.jsx)(n.code,{children:"bigint"})," instead of ",(0,a.jsx)(n.code,{children:"int"}),". In most cases a good index strategy will be more important than the integer representation. Here is a guide that benchmarks the performance of ",(0,a.jsx)(n.code,{children:"int"})," and ",(0,a.jsx)(n.code,{children:"bigint"})," in PostgreSQL: ",(0,a.jsx)(n.a,{href:"https://blog.rustprooflabs.com/2021/06/postgres-bigint-by-default",children:"Use BIGINT in Postgres"})]}),"\n",(0,a.jsx)(n.h4,{id:"ensuring-new-databases-are-created-with-the-new-representation",children:"Ensuring new databases are created with the new representation"}),"\n",(0,a.jsxs)(n.p,{children:["Since existing migrations won't be changed, databases that are created with these will still use ",(0,a.jsx)(n.code,{children:"int"})," to represent integers."]}),"\n",(0,a.jsx)(n.p,{children:"To ensure new databases are created with the new representation, the latest migration should be generated using Serverpod 2.0. It is enough to have an empty migration to ensure new databases use the new representation."}),"\n",(0,a.jsx)(n.p,{children:"A new empty migration can be created by running the following command in the terminal:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"$ serverpod create-migration --force\n"})}),"\n",(0,a.jsx)(n.h4,{id:"migration-of-existing-tables",children:"Migration of existing tables"}),"\n",(0,a.jsx)(n.p,{children:"The migration of existing tables to use the new representation will vary depending on the database content. Utilizing the wrong migration strategy might cause downtime for your application. That is the reason Serverpod does not automatically migrate existing tables."}),"\n",(0,a.jsx)(n.h5,{id:"small-tables",children:"Small tables"}),"\n",(0,a.jsx)(n.p,{children:"A simple way to migrate for small tables is to execute the following sql query to the database:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'ALTER SEQUENCE "my_table_id_seq" AS bigint;\nALTER TABLE "my_table" ALTER "id" TYPE bigint;\nALTER TABLE "my_table" ALTER "myNumber" TYPE bigint;\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The first two lines modify the id sequence for a table named ",(0,a.jsx)(n.code,{children:'"my_table"'})," to use ",(0,a.jsx)(n.code,{children:"bigint"})," instead of ",(0,a.jsx)(n.code,{children:"int"}),". The last line modifies a column of the same table to use ",(0,a.jsx)(n.code,{children:"bigint"}),". The drawback of this approach is that it locks the table during the migration. Therefore, this strategy is not recommended for large tables."]}),"\n",(0,a.jsx)(n.h5,{id:"large-tables",children:"Large tables"}),"\n",(0,a.jsx)(n.p,{children:"Migrating large tables without application downtime is a more complex operation, and the approach will vary depending on the data structure. Below are some gathered resources on the subject."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"http://zemanta.github.io/2021/08/25/column-migration-from-int-to-bigint-in-postgresql/",children:"Zemata - Column migration from INT to BIGINT"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://am2.co/2019/12/changing-a-column-from-int-to-bigint-without-downtime/",children:"AM^2 - Changing a column from int to bigint, without downtime"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://www.crunchydata.com/blog/the-integer-at-the-end-of-the-universe-integer-overflow-in-postgres",children:"Crunch data - The integer at the End of the Universe"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"changes-in-the-authentication-module",children:"Changes in the authentication module"}),"\n",(0,a.jsx)(n.h3,{id:"unsecure-random-disabled-by-default",children:"Unsecure random disabled by default"}),"\n",(0,a.jsxs)(n.p,{children:["The authentication module's default value for allowing unsecure random number generation is now ",(0,a.jsx)(n.code,{children:"false"}),". An exception will be thrown when trying to hash a password if no secure random number generator is available. To preserve the old behavior and enable unsecure random number generation, set the ",(0,a.jsx)(n.code,{children:"allowUnsecureRandom"})," property in the ",(0,a.jsx)(n.code,{children:"AuthConfig"})," to ",(0,a.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"auth.AuthConfig.set(auth.AuthConfig(\n allowUnsecureRandom: true,\n));\n"})}),"\n",(0,a.jsx)(n.h2,{id:"updates-to-serialization-in-serverpod-20",children:"Updates to Serialization in Serverpod 2.0"}),"\n",(0,a.jsx)(n.h3,{id:"general-changes-to-model-serialization",children:"General Changes to Model Serialization"}),"\n",(0,a.jsxs)(n.p,{children:["Serverpod 2.0 significantly streamlines the model serialization process. In earlier versions, the ",(0,a.jsx)(n.code,{children:"fromJson"})," factory constructors needed a ",(0,a.jsx)(n.code,{children:"serializationManager"})," parameter to handle object deserialization. This parameter has now been removed, enhancing simplicity and usability."]}),"\n",(0,a.jsx)(n.h4,{id:"before-change",children:"Before change"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final Map json = classInstance.toJson();\nfinal SerializationManager serializationManager = Protocol();\nfinal ClassName test = ClassName.fromJson(json, serializationManager);\n"})}),"\n",(0,a.jsx)(n.h4,{id:"after-change",children:"After change"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final Map json = classInstance.toJson();\nfinal ClassName test = ClassName.fromJson(json);\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enhancements-for-custom-serialization",children:"Enhancements for Custom Serialization"}),"\n",(0,a.jsxs)(n.p,{children:["The removal of the ",(0,a.jsx)(n.code,{children:"serializationManager"})," parameter in Serverpod 2.0 simplifies the serialization process not only for general models but also significantly enhances custom serialization workflows.\nFor custom classes that previously utilized unique serialization logic with the ",(0,a.jsx)(n.code,{children:"serializationManager"}),", adjustments may be necessary."]}),"\n",(0,a.jsx)(n.h4,{id:"previous-implementation",children:"Previous Implementation"}),"\n",(0,a.jsxs)(n.p,{children:["In the previous versions, models required the ",(0,a.jsx)(n.code,{children:"serializationManager"})," to be passed explicitly, as shown in the following code snippet:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"factory ClassName.fromJson(\n Map json,\n SerializationManager serializationManager,\n ) {\n return ClassName(\n json['name'],\n );\n }\n"})}),"\n",(0,a.jsx)(n.h4,{id:"updated-implementation",children:"Updated Implementation"}),"\n",(0,a.jsxs)(n.p,{children:["With the release of Serverpod 2.0, the ",(0,a.jsx)(n.code,{children:"fromJson"})," constructor has been simplified and the ",(0,a.jsx)(n.code,{children:"serializationManager"})," has been removed:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"factory ClassName.fromJson(\n Map json,\n ) {\n return ClassName(\n json['name'],\n );\n }\n"})}),"\n",(0,a.jsxs)(n.h2,{id:"deprecation-notice-for-serializableentity",children:["Deprecation Notice for ",(0,a.jsx)(n.code,{children:"SerializableEntity"})]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"SerializableEntity"})," class is deprecated and will be removed in version 2.1. Please implement the ",(0,a.jsx)(n.code,{children:"SerializableModel"})," interface instead for creating serializable models."]}),"\n",(0,a.jsx)(n.h3,{id:"migration-guide",children:"Migration Guide"}),"\n",(0,a.jsxs)(n.p,{children:["To migrate your code from ",(0,a.jsx)(n.code,{children:"SerializableEntity"})," to ",(0,a.jsx)(n.code,{children:"SerializableModel"}),", replace ",(0,a.jsx)(n.code,{children:"extends SerializableEntity"})," with ",(0,a.jsx)(n.code,{children:"implements SerializableModel"})," in your model classes."]}),"\n",(0,a.jsx)(n.h4,{id:"example",children:"Example"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Before:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"class CustomClass extends SerializableEntity {\n // Your code here\n}\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"After:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"class CustomClass implements SerializableModel {\n // Your code here\n}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const i={},s=a.createContext(i);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[27168],{65650:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>l});var a=t(74848),i=t(28453);const s={},r="Upgrade to 2.0",o={id:"upgrading/upgrade-to-two",title:"Upgrade to 2.0",description:"Changes to authentication",source:"@site/versioned_docs/version-2.0.0/12-upgrading/01-upgrade-to-two.md",sourceDirName:"12-upgrading",slug:"/upgrading/upgrade-to-two",permalink:"/2.0.0/upgrading/upgrade-to-two",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/versioned_docs/version-2.0.0/12-upgrading/01-upgrade-to-two.md",tags:[],version:"2.0.0",sidebarPosition:1,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Contribute",permalink:"/2.0.0/contribute"},next:{title:"Upgrade to 1.2",permalink:"/2.0.0/upgrading/upgrade-to-one-point-two"}},d={},l=[{value:"Changes to authentication",id:"changes-to-authentication",level:2},{value:"Advanced integrations",id:"advanced-integrations",level:3},{value:"Changes to the Session Object",id:"changes-to-the-session-object",level:2},{value:"Removed deprecated fields",id:"removed-deprecated-fields",level:3},{value:"Authenticated user information retrieval",id:"authenticated-user-information-retrieval",level:3},{value:"Authentication helpers",id:"authentication-helpers",level:3},{value:"Changes to database queries",id:"changes-to-database-queries",level:2},{value:"Removed unsafeQueryMappedResults(...)",id:"removed-unsafequerymappedresults",level:3},{value:"Update return type for delete operations",id:"update-return-type-for-delete-operations",level:3},{value:"Changes to database tables",id:"changes-to-database-tables",level:2},{value:"Integer representation changed to bigint",id:"integer-representation-changed-to-bigint",level:3},{value:"Why is this change made?",id:"why-is-this-change-made",level:4},{value:"Ensuring new databases are created with the new representation",id:"ensuring-new-databases-are-created-with-the-new-representation",level:4},{value:"Migration of existing tables",id:"migration-of-existing-tables",level:4},{value:"Small tables",id:"small-tables",level:5},{value:"Large tables",id:"large-tables",level:5},{value:"Changes in the authentication module",id:"changes-in-the-authentication-module",level:2},{value:"Unsecure random disabled by default",id:"unsecure-random-disabled-by-default",level:3},{value:"Updates to Serialization in Serverpod 2.0",id:"updates-to-serialization-in-serverpod-20",level:2},{value:"General Changes to Model Serialization",id:"general-changes-to-model-serialization",level:3},{value:"Before change",id:"before-change",level:4},{value:"After change",id:"after-change",level:4},{value:"Enhancements for Custom Serialization",id:"enhancements-for-custom-serialization",level:3},{value:"Previous Implementation",id:"previous-implementation",level:4},{value:"Updated Implementation",id:"updated-implementation",level:4},{value:"Deprecation Notice for SerializableEntity",id:"deprecation-notice-for-serializableentity",level:2},{value:"Migration Guide",id:"migration-guide",level:3},{value:"Example",id:"example",level:4}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"upgrade-to-20",children:"Upgrade to 2.0"})}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-authentication",children:"Changes to authentication"}),"\n",(0,a.jsxs)(n.p,{children:["The base auth implementation has been removed from Serverpod core and moved into the ",(0,a.jsx)(n.code,{children:"serverpod_auth"})," package. If you are not using authentication at all this change does not impact you. If you are using the auth module already the transition is simple."]}),"\n",(0,a.jsxs)(n.p,{children:["The default authentication handler will now throw an ",(0,a.jsx)(n.code,{children:"UnimplementedError"}),". It is now required to supply the authentication handler to the Serverpod object, in your server.dart file make the following change:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"import 'package:serverpod_auth_server/serverpod_auth_server.dart' as auth;\n\nvoid run(List args) async {\n var pod = Serverpod(\n args,\n Protocol(),\n Endpoints(),\n authenticationHandler: auth.authenticationHandler, // Add this line\n );\n\n ...\n}\n"})}),"\n",(0,a.jsx)(n.h3,{id:"advanced-integrations",children:"Advanced integrations"}),"\n",(0,a.jsxs)(n.p,{children:["The methods ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," now takes the session object as a param and is no longer available on the session object. Instead import the class ",(0,a.jsx)(n.code,{children:"UserAuthentication"})," from the auth module to access these static methods."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"UserAuthentication.signInUser(session, userId, 'provider');\n\nUserAuthentication.signOutUser(session);\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The table ",(0,a.jsx)(n.code,{children:"serverpod_auth_key"})," has been removed from Serverpod core but is available in the serverpod_auth module instead. This means that if you wrote a custom integration before without using the serverpod_auth module you have to take care of managing your token implementation."]}),"\n",(0,a.jsxs)(n.p,{children:["Adding the definition of the ",(0,a.jsx)(n.code,{children:"serverpod_auth_key"})," table to your project is the simplest way to do a seamless migration."]}),"\n",(0,a.jsx)(n.p,{children:"The table was defined in the following way:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"### Provides a method of access for a user to authenticate with the server.\nclass: AuthKey\ntable: serverpod_auth_key\nfields:\n ### The id of the user to provide access to.\n userId: int\n\n ### The hashed version of the key.\n hash: String\n\n ### The key sent to the server to authenticate.\n key: String?, !persist\n\n ### The scopes this key provides access to.\n scopeNames: List\n\n ### The method of signing in this key was generated through. This can be email\n ### or different social logins.\n method: String\nindexes:\n serverpod_auth_key_userId_idx:\n fields: userId\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Your are then responsible for creating/removing entries in this table, the old ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," that used to provide this functionality can be found ",(0,a.jsx)(n.a,{href:"https://github.com/serverpod/serverpod/blob/13795a7bd4c0cc5a03101b6f378cb914673046dd/packages/serverpod/lib/src/server/session.dart#L359-L394",children:"here"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-the-session-object",children:"Changes to the Session Object"}),"\n",(0,a.jsx)(n.h3,{id:"removed-deprecated-fields",children:"Removed deprecated fields"}),"\n",(0,a.jsxs)(n.p,{children:["With Serverpod 2.0, we have removed the deprecated legacy database layer from the ",(0,a.jsx)(n.code,{children:"Session"})," object. The ",(0,a.jsx)(n.code,{children:"Session"})," object now incorporates the new database layer, accessed via the ",(0,a.jsx)(n.code,{children:"dbNext"})," field in Serverpod 1.2, under the ",(0,a.jsx)(n.code,{children:"db"})," field."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"session.dbNext.find(...);\n"})}),"\n",(0,a.jsx)(n.p,{children:"becomes"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"session.db.find(...);\n"})}),"\n",(0,a.jsx)(n.h3,{id:"authenticated-user-information-retrieval",children:"Authenticated user information retrieval"}),"\n",(0,a.jsxs)(n.p,{children:["In Serverpod 2.0, we have removed the getters ",(0,a.jsx)(n.code,{children:"scopes"})," and ",(0,a.jsx)(n.code,{children:"authenticatedUser"})," from session. This information is now retrievable through the ",(0,a.jsx)(n.code,{children:"authenticated"})," getter as fields of the returned object."]}),"\n",(0,a.jsx)(n.p,{children:"Replace this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"int? userId = await session.auth.authenticatedUser;\n\nSet? scopes = await session.scopes;\n"})}),"\n",(0,a.jsx)(n.p,{children:"With this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final authenticated = await session.authenticated;\n\n//Read authenticated userId\nint? userId = authenticated?.userId;\n\n//Read scopes\nSet? scopes = authenticated?.scopes;\n"})}),"\n",(0,a.jsxs)(n.p,{children:["If the ",(0,a.jsx)(n.code,{children:"authenticated"})," property is set on the session it effectively means there is an authenticated user making the request."]}),"\n",(0,a.jsx)(n.h3,{id:"authentication-helpers",children:"Authentication helpers"}),"\n",(0,a.jsxs)(n.p,{children:["The field ",(0,a.jsx)(n.code,{children:"auth"})," has been removed and the methods ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," have been moved to the ",(0,a.jsx)(n.code,{children:"serverpod_auth"})," module."]}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-database-queries",children:"Changes to database queries"}),"\n",(0,a.jsx)(n.h3,{id:"removed-unsafequerymappedresults",children:"Removed unsafeQueryMappedResults(...)"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," method has been removed. A similar result can now instead be formatted from the ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," result by calling the ",(0,a.jsx)(n.code,{children:"toColumnMap()"})," method for each row of the result. ",(0,a.jsx)(n.code,{children:"toColumnMap"})," returns a map containing the query alias for the column as key and the row-column value as value."]}),"\n",(0,a.jsx)(n.p,{children:"Given a query that performs a join like this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'SELECT\n "company"."id" AS "company.id",\n "company"."name" AS "company.name",\n "company"."townId" AS "company.townId",\n "company_town_town"."id" AS "company_town_town.id",\n "company_town_town"."name" AS "company_town_town.name",\n "company_town_town"."mayorId" AS "company_town_town.mayorId"\nFROM\n "company"\nLEFT JOIN\n "town" AS "company_town_town" ON "company"."townId" = "company_town_town"."id"\nORDER BY\n "company"."name"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The return type from ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," in 1.2 was:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company": {\n "company.id": 40,\n "company.name": "Apple",\n "company.townId": 64\n },\n "town": {\n "company_town_town.id": 64,\n "company_town_town.name": "San Francisco",\n "company_town_town.mayorId": null\n }\n },\n {\n "company": {\n "company.id": 39,\n "company.name": "Serverpod",\n "company.townId": 63\n },\n "town": {\n "company_town_town.id": 63,\n "company_town_town.name": "Stockholm",\n "company_town_town.mayorId": null\n }\n }\n]\n'})}),"\n",(0,a.jsxs)(n.p,{children:["And if ",(0,a.jsx)(n.code,{children:"result.map((row) => row.toColumnMap())"})," is used to format the result from ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," in 2.0, the following result is obtained:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company.id": 38,\n "company.name": "Apple",\n "company.townId": 62,\n "company_town_town.id": 62,\n "company_town_town.name": "San Francisco",\n "company_town_town.mayorId": null\n },\n {\n "company.id": 37,\n "company.name": "Serverpod",\n "company.townId": 61,\n "company_town_town.id": 61,\n "company_town_town.name": "Stockholm",\n "company_town_town.mayorId": null\n }\n]\n'})}),"\n",(0,a.jsx)(n.p,{children:"or for a simple query without aliases:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'SELECT\n "id",\n "name",\n "townId"\nFROM\n "company"\nORDER BY\n "name"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["the return type from ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," in 1.2 was:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company": {\n "id": 54,\n "name": "Apple",\n "townId": 86\n }\n },\n {\n "company": {\n "id": 53,\n "name": "Serverpod",\n "townId": 85\n }\n }\n]\n'})}),"\n",(0,a.jsxs)(n.p,{children:["and if ",(0,a.jsx)(n.code,{children:"result.map((row) => row.toColumnMap())"})," is used to format the result from ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," in 2.0, the following result is obtained:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:' [\n {\n "id": 54,\n "name": "Apple",\n "townId": 86\n },\n {\n "id": 53,\n "name": "Serverpod",\n "townId": 85\n }\n]\n'})}),"\n",(0,a.jsx)(n.h3,{id:"update-return-type-for-delete-operations",children:"Update return type for delete operations"}),"\n",(0,a.jsxs)(n.p,{children:["The return type for all delete operations has been changed from the ",(0,a.jsx)(n.code,{children:"id"})," of the deleted rows to the actual deleted rows. This makes the return type for the delete operations consistent with the return type of the other database operations. It also dramatically simplifies retrieving and removing rows in concurrent environments."]}),"\n",(0,a.jsx)(n.p,{children:"Return type before the change:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"int companyId = await Company.db.deleteRow(session, company);\nList companyIds = await Company.db.delete(session, [company]);\nList companyIds = await Company.db.deleteWhere(session, where: (t) => t.name.like('%Ltd'));\n"})}),"\n",(0,a.jsx)(n.p,{children:"Return types after the change:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"Company company = await Company.db.deleteRow(session, company);\nList companies = await Company.db.delete(session, [company]);\nList companies = await Company.db.deleteWhere(session, where: (t) => t.name.like('%Ltd'));\n"})}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-database-tables",children:"Changes to database tables"}),"\n",(0,a.jsx)(n.h3,{id:"integer-representation-changed-to-bigint",children:"Integer representation changed to bigint"}),"\n",(0,a.jsxs)(n.p,{children:["Integer representation in the database has changed from ",(0,a.jsx)(n.code,{children:"int"})," to ",(0,a.jsx)(n.code,{children:"bigint"}),". From now on, models with ",(0,a.jsx)(n.code,{children:"int"})," fields will generate database migrations where that field is defined as a ",(0,a.jsx)(n.code,{children:"bigint"})," type in the database."]}),"\n",(0,a.jsxs)(n.p,{children:["This change also applies to the ",(0,a.jsx)(n.code,{children:"id"})," field of models where ",(0,a.jsx)(n.code,{children:"bigserial"})," is now used to generate the id."]}),"\n",(0,a.jsx)(n.p,{children:"The change is compatible with existing databases. Existing migrations therefore, won't be changed by the Serverpod migration system. No manual modification to the database is required if this data representation is not essential for the application. However, all new migrations will be created with the new representation."}),"\n",(0,a.jsx)(n.h4,{id:"why-is-this-change-made",children:"Why is this change made?"}),"\n",(0,a.jsxs)(n.p,{children:["The change was made to ensure that ",(0,a.jsx)(n.a,{href:"https://dart.dev/guides/language/numbers",children:"Dart"})," and the database representation of integers is consistent. Dart uses 64-bit integers, and the ",(0,a.jsx)(n.code,{children:"int"})," type in Dart is a 64-bit integer. The ",(0,a.jsx)(n.code,{children:"int"})," type in PostgreSQL is a 32-bit integer. This means that the ",(0,a.jsx)(n.code,{children:"int"})," type in Dart can represent larger numbers than the ",(0,a.jsx)(n.code,{children:"int"})," type in PostgreSQL. By using ",(0,a.jsx)(n.code,{children:"bigint"})," in PostgreSQL, the integer representation is consistent between Dart and the database."]}),"\n",(0,a.jsxs)(n.p,{children:["In terms of performance, there are usually no significant drawbacks with using ",(0,a.jsx)(n.code,{children:"bigint"})," instead of ",(0,a.jsx)(n.code,{children:"int"}),". In most cases a good index strategy will be more important than the integer representation. Here is a guide that benchmarks the performance of ",(0,a.jsx)(n.code,{children:"int"})," and ",(0,a.jsx)(n.code,{children:"bigint"})," in PostgreSQL: ",(0,a.jsx)(n.a,{href:"https://blog.rustprooflabs.com/2021/06/postgres-bigint-by-default",children:"Use BIGINT in Postgres"})]}),"\n",(0,a.jsx)(n.h4,{id:"ensuring-new-databases-are-created-with-the-new-representation",children:"Ensuring new databases are created with the new representation"}),"\n",(0,a.jsxs)(n.p,{children:["Since existing migrations won't be changed, databases that are created with these will still use ",(0,a.jsx)(n.code,{children:"int"})," to represent integers."]}),"\n",(0,a.jsx)(n.p,{children:"To ensure new databases are created with the new representation, the latest migration should be generated using Serverpod 2.0. It is enough to have an empty migration to ensure new databases use the new representation."}),"\n",(0,a.jsx)(n.p,{children:"A new empty migration can be created by running the following command in the terminal:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"$ serverpod create-migration --force\n"})}),"\n",(0,a.jsx)(n.h4,{id:"migration-of-existing-tables",children:"Migration of existing tables"}),"\n",(0,a.jsx)(n.p,{children:"The migration of existing tables to use the new representation will vary depending on the database content. Utilizing the wrong migration strategy might cause downtime for your application. That is the reason Serverpod does not automatically migrate existing tables."}),"\n",(0,a.jsx)(n.h5,{id:"small-tables",children:"Small tables"}),"\n",(0,a.jsx)(n.p,{children:"A simple way to migrate for small tables is to execute the following sql query to the database:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'ALTER SEQUENCE "my_table_id_seq" AS bigint;\nALTER TABLE "my_table" ALTER "id" TYPE bigint;\nALTER TABLE "my_table" ALTER "myNumber" TYPE bigint;\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The first two lines modify the id sequence for a table named ",(0,a.jsx)(n.code,{children:'"my_table"'})," to use ",(0,a.jsx)(n.code,{children:"bigint"})," instead of ",(0,a.jsx)(n.code,{children:"int"}),". The last line modifies a column of the same table to use ",(0,a.jsx)(n.code,{children:"bigint"}),". The drawback of this approach is that it locks the table during the migration. Therefore, this strategy is not recommended for large tables."]}),"\n",(0,a.jsx)(n.h5,{id:"large-tables",children:"Large tables"}),"\n",(0,a.jsx)(n.p,{children:"Migrating large tables without application downtime is a more complex operation, and the approach will vary depending on the data structure. Below are some gathered resources on the subject."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"http://zemanta.github.io/2021/08/25/column-migration-from-int-to-bigint-in-postgresql/",children:"Zemata - Column migration from INT to BIGINT"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://am2.co/2019/12/changing-a-column-from-int-to-bigint-without-downtime/",children:"AM^2 - Changing a column from int to bigint, without downtime"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://www.crunchydata.com/blog/the-integer-at-the-end-of-the-universe-integer-overflow-in-postgres",children:"Crunch data - The integer at the End of the Universe"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"changes-in-the-authentication-module",children:"Changes in the authentication module"}),"\n",(0,a.jsx)(n.h3,{id:"unsecure-random-disabled-by-default",children:"Unsecure random disabled by default"}),"\n",(0,a.jsxs)(n.p,{children:["The authentication module's default value for allowing unsecure random number generation is now ",(0,a.jsx)(n.code,{children:"false"}),". An exception will be thrown when trying to hash a password if no secure random number generator is available. To preserve the old behavior and enable unsecure random number generation, set the ",(0,a.jsx)(n.code,{children:"allowUnsecureRandom"})," property in the ",(0,a.jsx)(n.code,{children:"AuthConfig"})," to ",(0,a.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"auth.AuthConfig.set(auth.AuthConfig(\n allowUnsecureRandom: true,\n));\n"})}),"\n",(0,a.jsx)(n.h2,{id:"updates-to-serialization-in-serverpod-20",children:"Updates to Serialization in Serverpod 2.0"}),"\n",(0,a.jsx)(n.h3,{id:"general-changes-to-model-serialization",children:"General Changes to Model Serialization"}),"\n",(0,a.jsxs)(n.p,{children:["Serverpod 2.0 significantly streamlines the model serialization process. In earlier versions, the ",(0,a.jsx)(n.code,{children:"fromJson"})," factory constructors needed a ",(0,a.jsx)(n.code,{children:"serializationManager"})," parameter to handle object deserialization. This parameter has now been removed, enhancing simplicity and usability."]}),"\n",(0,a.jsx)(n.h4,{id:"before-change",children:"Before change"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final Map json = classInstance.toJson();\nfinal SerializationManager serializationManager = Protocol();\nfinal ClassName test = ClassName.fromJson(json, serializationManager);\n"})}),"\n",(0,a.jsx)(n.h4,{id:"after-change",children:"After change"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final Map json = classInstance.toJson();\nfinal ClassName test = ClassName.fromJson(json);\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enhancements-for-custom-serialization",children:"Enhancements for Custom Serialization"}),"\n",(0,a.jsxs)(n.p,{children:["The removal of the ",(0,a.jsx)(n.code,{children:"serializationManager"})," parameter in Serverpod 2.0 simplifies the serialization process not only for general models but also significantly enhances custom serialization workflows.\nFor custom classes that previously utilized unique serialization logic with the ",(0,a.jsx)(n.code,{children:"serializationManager"}),", adjustments may be necessary."]}),"\n",(0,a.jsx)(n.h4,{id:"previous-implementation",children:"Previous Implementation"}),"\n",(0,a.jsxs)(n.p,{children:["In the previous versions, models required the ",(0,a.jsx)(n.code,{children:"serializationManager"})," to be passed explicitly, as shown in the following code snippet:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"factory ClassName.fromJson(\n Map json,\n SerializationManager serializationManager,\n ) {\n return ClassName(\n json['name'],\n );\n }\n"})}),"\n",(0,a.jsx)(n.h4,{id:"updated-implementation",children:"Updated Implementation"}),"\n",(0,a.jsxs)(n.p,{children:["With the release of Serverpod 2.0, the ",(0,a.jsx)(n.code,{children:"fromJson"})," constructor has been simplified and the ",(0,a.jsx)(n.code,{children:"serializationManager"})," has been removed:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"factory ClassName.fromJson(\n Map json,\n ) {\n return ClassName(\n json['name'],\n );\n }\n"})}),"\n",(0,a.jsxs)(n.h2,{id:"deprecation-notice-for-serializableentity",children:["Deprecation Notice for ",(0,a.jsx)(n.code,{children:"SerializableEntity"})]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"SerializableEntity"})," class is deprecated and will be removed in version 3. Please implement the ",(0,a.jsx)(n.code,{children:"SerializableModel"})," interface instead for creating serializable models."]}),"\n",(0,a.jsx)(n.h3,{id:"migration-guide",children:"Migration Guide"}),"\n",(0,a.jsxs)(n.p,{children:["To migrate your code from ",(0,a.jsx)(n.code,{children:"SerializableEntity"})," to ",(0,a.jsx)(n.code,{children:"SerializableModel"}),", replace ",(0,a.jsx)(n.code,{children:"extends SerializableEntity"})," with ",(0,a.jsx)(n.code,{children:"implements SerializableModel"})," in your model classes."]}),"\n",(0,a.jsx)(n.h4,{id:"example",children:"Example"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Before:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"class CustomClass extends SerializableEntity {\n // Your code here\n}\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"After:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"class CustomClass implements SerializableModel {\n // Your code here\n}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const i={},s=a.createContext(i);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/8615e055.46cbd86e.js b/docs/assets/js/8615e055.a738aae6.js similarity index 93% rename from docs/assets/js/8615e055.46cbd86e.js rename to docs/assets/js/8615e055.a738aae6.js index 89fcf8cc5..3e3f9985b 100644 --- a/docs/assets/js/8615e055.46cbd86e.js +++ b/docs/assets/js/8615e055.a738aae6.js @@ -1 +1 @@ -"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[76238],{16681:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>l});var a=t(74848),i=t(28453);const s={},r="Upgrade to 2.0",o={id:"upgrading/upgrade-to-two",title:"Upgrade to 2.0",description:"Changes to authentication",source:"@site/docs/08-upgrading/03-upgrade-to-two.md",sourceDirName:"08-upgrading",slug:"/upgrading/upgrade-to-two",permalink:"/next/upgrading/upgrade-to-two",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/docs/08-upgrading/03-upgrade-to-two.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Upgrade to 1.2",permalink:"/next/upgrading/upgrade-to-one-point-two"},next:{title:"Serverpod Insights",permalink:"/next/tools/insights"}},d={},l=[{value:"Changes to authentication",id:"changes-to-authentication",level:2},{value:"Advanced integrations",id:"advanced-integrations",level:3},{value:"Changes to the Session Object",id:"changes-to-the-session-object",level:2},{value:"Removed deprecated fields",id:"removed-deprecated-fields",level:3},{value:"Authenticated user information retrieval",id:"authenticated-user-information-retrieval",level:3},{value:"Authentication helpers",id:"authentication-helpers",level:3},{value:"Changes to database queries",id:"changes-to-database-queries",level:2},{value:"Removed unsafeQueryMappedResults(...)",id:"removed-unsafequerymappedresults",level:3},{value:"Update return type for delete operations",id:"update-return-type-for-delete-operations",level:3},{value:"Changes to database tables",id:"changes-to-database-tables",level:2},{value:"Integer representation changed to bigint",id:"integer-representation-changed-to-bigint",level:3},{value:"Why is this change made?",id:"why-is-this-change-made",level:4},{value:"Ensuring new databases are created with the new representation",id:"ensuring-new-databases-are-created-with-the-new-representation",level:4},{value:"Migration of existing tables",id:"migration-of-existing-tables",level:4},{value:"Small tables",id:"small-tables",level:5},{value:"Large tables",id:"large-tables",level:5},{value:"Changes in the authentication module",id:"changes-in-the-authentication-module",level:2},{value:"Unsecure random disabled by default",id:"unsecure-random-disabled-by-default",level:3},{value:"Updates to Serialization in Serverpod 2.0",id:"updates-to-serialization-in-serverpod-20",level:2},{value:"General Changes to Model Serialization",id:"general-changes-to-model-serialization",level:3},{value:"Before change",id:"before-change",level:4},{value:"After change",id:"after-change",level:4},{value:"Enhancements for Custom Serialization",id:"enhancements-for-custom-serialization",level:3},{value:"Previous Implementation",id:"previous-implementation",level:4},{value:"Updated Implementation",id:"updated-implementation",level:4},{value:"Deprecation Notice for SerializableEntity",id:"deprecation-notice-for-serializableentity",level:2},{value:"Migration Guide",id:"migration-guide",level:3},{value:"Example",id:"example",level:4}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"upgrade-to-20",children:"Upgrade to 2.0"})}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-authentication",children:"Changes to authentication"}),"\n",(0,a.jsxs)(n.p,{children:["The base auth implementation has been removed from Serverpod core and moved into the ",(0,a.jsx)(n.code,{children:"serverpod_auth"})," package. If you are not using authentication at all this change does not impact you. If you are using the auth module already the transition is simple."]}),"\n",(0,a.jsxs)(n.p,{children:["The default authentication handler will now throw an ",(0,a.jsx)(n.code,{children:"UnimplementedError"}),". It is now required to supply the authentication handler to the Serverpod object, in your server.dart file make the following change:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"import 'package:serverpod_auth_server/serverpod_auth_server.dart' as auth;\n\nvoid run(List args) async {\n var pod = Serverpod(\n args,\n Protocol(),\n Endpoints(),\n authenticationHandler: auth.authenticationHandler, // Add this line\n );\n\n ...\n}\n"})}),"\n",(0,a.jsx)(n.h3,{id:"advanced-integrations",children:"Advanced integrations"}),"\n",(0,a.jsxs)(n.p,{children:["The methods ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," now takes the session object as a param and is no longer available on the session object. Instead import the class ",(0,a.jsx)(n.code,{children:"UserAuthentication"})," from the auth module to access these static methods."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"UserAuthentication.signInUser(session, userId, 'provider');\n\nUserAuthentication.signOutUser(session);\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The table ",(0,a.jsx)(n.code,{children:"serverpod_auth_key"})," has been removed from Serverpod core but is available in the serverpod_auth module instead. This means that if you wrote a custom integration before without using the serverpod_auth module you have to take care of managing your token implementation."]}),"\n",(0,a.jsxs)(n.p,{children:["Adding the definition of the ",(0,a.jsx)(n.code,{children:"serverpod_auth_key"})," table to your project is the simplest way to do a seamless migration."]}),"\n",(0,a.jsx)(n.p,{children:"The table was defined in the following way:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"### Provides a method of access for a user to authenticate with the server.\nclass: AuthKey\ntable: serverpod_auth_key\nfields:\n ### The id of the user to provide access to.\n userId: int\n\n ### The hashed version of the key.\n hash: String\n\n ### The key sent to the server to authenticate.\n key: String?, !persist\n\n ### The scopes this key provides access to.\n scopeNames: List\n\n ### The method of signing in this key was generated through. This can be email\n ### or different social logins.\n method: String\nindexes:\n serverpod_auth_key_userId_idx:\n fields: userId\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Your are then responsible for creating/removing entries in this table, the old ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," that used to provide this functionality can be found ",(0,a.jsx)(n.a,{href:"https://github.com/serverpod/serverpod/blob/13795a7bd4c0cc5a03101b6f378cb914673046dd/packages/serverpod/lib/src/server/session.dart#L359-L394",children:"here"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-the-session-object",children:"Changes to the Session Object"}),"\n",(0,a.jsx)(n.h3,{id:"removed-deprecated-fields",children:"Removed deprecated fields"}),"\n",(0,a.jsxs)(n.p,{children:["With Serverpod 2.0, we have removed the deprecated legacy database layer from the ",(0,a.jsx)(n.code,{children:"Session"})," object. The ",(0,a.jsx)(n.code,{children:"Session"})," object now incorporates the new database layer, accessed via the ",(0,a.jsx)(n.code,{children:"dbNext"})," field in Serverpod 1.2, under the ",(0,a.jsx)(n.code,{children:"db"})," field."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"session.dbNext.find(...);\n"})}),"\n",(0,a.jsx)(n.p,{children:"becomes"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"session.db.find(...);\n"})}),"\n",(0,a.jsx)(n.h3,{id:"authenticated-user-information-retrieval",children:"Authenticated user information retrieval"}),"\n",(0,a.jsxs)(n.p,{children:["In Serverpod 2.0, we have removed the getters ",(0,a.jsx)(n.code,{children:"scopes"})," and ",(0,a.jsx)(n.code,{children:"authenticatedUser"})," from session. This information is now retrievable through the ",(0,a.jsx)(n.code,{children:"authenticated"})," getter as fields of the returned object."]}),"\n",(0,a.jsx)(n.p,{children:"Replace this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"int? userId = await session.auth.authenticatedUser;\n\nSet? scopes = await session.scopes;\n"})}),"\n",(0,a.jsx)(n.p,{children:"With this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final authenticated = await session.authenticated;\n\n//Read authenticated userId\nint? userId = authenticated?.userId;\n\n//Read scopes\nSet? scopes = authenticated?.scopes;\n"})}),"\n",(0,a.jsxs)(n.p,{children:["If the ",(0,a.jsx)(n.code,{children:"authenticated"})," property is set on the session it effectively means there is an authenticated user making the request."]}),"\n",(0,a.jsx)(n.h3,{id:"authentication-helpers",children:"Authentication helpers"}),"\n",(0,a.jsxs)(n.p,{children:["The field ",(0,a.jsx)(n.code,{children:"auth"})," has been removed and the methods ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," have been moved to the ",(0,a.jsx)(n.code,{children:"serverpod_auth"})," module."]}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-database-queries",children:"Changes to database queries"}),"\n",(0,a.jsx)(n.h3,{id:"removed-unsafequerymappedresults",children:"Removed unsafeQueryMappedResults(...)"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," method has been removed. A similar result can now instead be formatted from the ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," result by calling the ",(0,a.jsx)(n.code,{children:"toColumnMap()"})," method for each row of the result. ",(0,a.jsx)(n.code,{children:"toColumnMap"})," returns a map containing the query alias for the column as key and the row-column value as value."]}),"\n",(0,a.jsx)(n.p,{children:"Given a query that performs a join like this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'SELECT\n "company"."id" AS "company.id",\n "company"."name" AS "company.name",\n "company"."townId" AS "company.townId",\n "company_town_town"."id" AS "company_town_town.id",\n "company_town_town"."name" AS "company_town_town.name",\n "company_town_town"."mayorId" AS "company_town_town.mayorId"\nFROM\n "company"\nLEFT JOIN\n "town" AS "company_town_town" ON "company"."townId" = "company_town_town"."id"\nORDER BY\n "company"."name"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The return type from ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," in 1.2 was:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company": {\n "company.id": 40,\n "company.name": "Apple",\n "company.townId": 64\n },\n "town": {\n "company_town_town.id": 64,\n "company_town_town.name": "San Francisco",\n "company_town_town.mayorId": null\n }\n },\n {\n "company": {\n "company.id": 39,\n "company.name": "Serverpod",\n "company.townId": 63\n },\n "town": {\n "company_town_town.id": 63,\n "company_town_town.name": "Stockholm",\n "company_town_town.mayorId": null\n }\n }\n]\n'})}),"\n",(0,a.jsxs)(n.p,{children:["And if ",(0,a.jsx)(n.code,{children:"result.map((row) => row.toColumnMap())"})," is used to format the result from ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," in 2.0, the following result is obtained:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company.id": 38,\n "company.name": "Apple",\n "company.townId": 62,\n "company_town_town.id": 62,\n "company_town_town.name": "San Francisco",\n "company_town_town.mayorId": null\n },\n {\n "company.id": 37,\n "company.name": "Serverpod",\n "company.townId": 61,\n "company_town_town.id": 61,\n "company_town_town.name": "Stockholm",\n "company_town_town.mayorId": null\n }\n]\n'})}),"\n",(0,a.jsx)(n.p,{children:"or for a simple query without aliases:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'SELECT\n "id",\n "name",\n "townId"\nFROM\n "company"\nORDER BY\n "name"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["the return type from ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," in 1.2 was:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company": {\n "id": 54,\n "name": "Apple",\n "townId": 86\n }\n },\n {\n "company": {\n "id": 53,\n "name": "Serverpod",\n "townId": 85\n }\n }\n]\n'})}),"\n",(0,a.jsxs)(n.p,{children:["and if ",(0,a.jsx)(n.code,{children:"result.map((row) => row.toColumnMap())"})," is used to format the result from ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," in 2.0, the following result is obtained:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:' [\n {\n "id": 54,\n "name": "Apple",\n "townId": 86\n },\n {\n "id": 53,\n "name": "Serverpod",\n "townId": 85\n }\n]\n'})}),"\n",(0,a.jsx)(n.h3,{id:"update-return-type-for-delete-operations",children:"Update return type for delete operations"}),"\n",(0,a.jsxs)(n.p,{children:["The return type for all delete operations has been changed from the ",(0,a.jsx)(n.code,{children:"id"})," of the deleted rows to the actual deleted rows. This makes the return type for the delete operations consistent with the return type of the other database operations. It also dramatically simplifies retrieving and removing rows in concurrent environments."]}),"\n",(0,a.jsx)(n.p,{children:"Return type before the change:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"int companyId = await Company.db.deleteRow(session, company);\nList companyIds = await Company.db.delete(session, [company]);\nList companyIds = await Company.db.deleteWhere(session, where: (t) => t.name.like('%Ltd'));\n"})}),"\n",(0,a.jsx)(n.p,{children:"Return types after the change:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"Company company = await Company.db.deleteRow(session, company);\nList companies = await Company.db.delete(session, [company]);\nList companies = await Company.db.deleteWhere(session, where: (t) => t.name.like('%Ltd'));\n"})}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-database-tables",children:"Changes to database tables"}),"\n",(0,a.jsx)(n.h3,{id:"integer-representation-changed-to-bigint",children:"Integer representation changed to bigint"}),"\n",(0,a.jsxs)(n.p,{children:["Integer representation in the database has changed from ",(0,a.jsx)(n.code,{children:"int"})," to ",(0,a.jsx)(n.code,{children:"bigint"}),". From now on, models with ",(0,a.jsx)(n.code,{children:"int"})," fields will generate database migrations where that field is defined as a ",(0,a.jsx)(n.code,{children:"bigint"})," type in the database."]}),"\n",(0,a.jsxs)(n.p,{children:["This change also applies to the ",(0,a.jsx)(n.code,{children:"id"})," field of models where ",(0,a.jsx)(n.code,{children:"bigserial"})," is now used to generate the id."]}),"\n",(0,a.jsx)(n.p,{children:"The change is compatible with existing databases. Existing migrations therefore, won't be changed by the Serverpod migration system. No manual modification to the database is required if this data representation is not essential for the application. However, all new migrations will be created with the new representation."}),"\n",(0,a.jsx)(n.h4,{id:"why-is-this-change-made",children:"Why is this change made?"}),"\n",(0,a.jsxs)(n.p,{children:["The change was made to ensure that ",(0,a.jsx)(n.a,{href:"https://dart.dev/guides/language/numbers",children:"Dart"})," and the database representation of integers is consistent. Dart uses 64-bit integers, and the ",(0,a.jsx)(n.code,{children:"int"})," type in Dart is a 64-bit integer. The ",(0,a.jsx)(n.code,{children:"int"})," type in PostgreSQL is a 32-bit integer. This means that the ",(0,a.jsx)(n.code,{children:"int"})," type in Dart can represent larger numbers than the ",(0,a.jsx)(n.code,{children:"int"})," type in PostgreSQL. By using ",(0,a.jsx)(n.code,{children:"bigint"})," in PostgreSQL, the integer representation is consistent between Dart and the database."]}),"\n",(0,a.jsxs)(n.p,{children:["In terms of performance, there are usually no significant drawbacks with using ",(0,a.jsx)(n.code,{children:"bigint"})," instead of ",(0,a.jsx)(n.code,{children:"int"}),". In most cases a good index strategy will be more important than the integer representation. Here is a guide that benchmarks the performance of ",(0,a.jsx)(n.code,{children:"int"})," and ",(0,a.jsx)(n.code,{children:"bigint"})," in PostgreSQL: ",(0,a.jsx)(n.a,{href:"https://blog.rustprooflabs.com/2021/06/postgres-bigint-by-default",children:"Use BIGINT in Postgres"})]}),"\n",(0,a.jsx)(n.h4,{id:"ensuring-new-databases-are-created-with-the-new-representation",children:"Ensuring new databases are created with the new representation"}),"\n",(0,a.jsxs)(n.p,{children:["Since existing migrations won't be changed, databases that are created with these will still use ",(0,a.jsx)(n.code,{children:"int"})," to represent integers."]}),"\n",(0,a.jsx)(n.p,{children:"To ensure new databases are created with the new representation, the latest migration should be generated using Serverpod 2.0. It is enough to have an empty migration to ensure new databases use the new representation."}),"\n",(0,a.jsx)(n.p,{children:"A new empty migration can be created by running the following command in the terminal:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"$ serverpod create-migration --force\n"})}),"\n",(0,a.jsx)(n.h4,{id:"migration-of-existing-tables",children:"Migration of existing tables"}),"\n",(0,a.jsx)(n.p,{children:"The migration of existing tables to use the new representation will vary depending on the database content. Utilizing the wrong migration strategy might cause downtime for your application. That is the reason Serverpod does not automatically migrate existing tables."}),"\n",(0,a.jsx)(n.h5,{id:"small-tables",children:"Small tables"}),"\n",(0,a.jsx)(n.p,{children:"A simple way to migrate for small tables is to execute the following sql query to the database:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'ALTER SEQUENCE "my_table_id_seq" AS bigint;\nALTER TABLE "my_table" ALTER "id" TYPE bigint;\nALTER TABLE "my_table" ALTER "myNumber" TYPE bigint;\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The first two lines modify the id sequence for a table named ",(0,a.jsx)(n.code,{children:'"my_table"'})," to use ",(0,a.jsx)(n.code,{children:"bigint"})," instead of ",(0,a.jsx)(n.code,{children:"int"}),". The last line modifies a column of the same table to use ",(0,a.jsx)(n.code,{children:"bigint"}),". The drawback of this approach is that it locks the table during the migration. Therefore, this strategy is not recommended for large tables."]}),"\n",(0,a.jsx)(n.h5,{id:"large-tables",children:"Large tables"}),"\n",(0,a.jsx)(n.p,{children:"Migrating large tables without application downtime is a more complex operation, and the approach will vary depending on the data structure. Below are some gathered resources on the subject."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"http://zemanta.github.io/2021/08/25/column-migration-from-int-to-bigint-in-postgresql/",children:"Zemata - Column migration from INT to BIGINT"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://am2.co/2019/12/changing-a-column-from-int-to-bigint-without-downtime/",children:"AM^2 - Changing a column from int to bigint, without downtime"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://www.crunchydata.com/blog/the-integer-at-the-end-of-the-universe-integer-overflow-in-postgres",children:"Crunch data - The integer at the End of the Universe"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"changes-in-the-authentication-module",children:"Changes in the authentication module"}),"\n",(0,a.jsx)(n.h3,{id:"unsecure-random-disabled-by-default",children:"Unsecure random disabled by default"}),"\n",(0,a.jsxs)(n.p,{children:["The authentication module's default value for allowing unsecure random number generation is now ",(0,a.jsx)(n.code,{children:"false"}),". An exception will be thrown when trying to hash a password if no secure random number generator is available. To preserve the old behavior and enable unsecure random number generation, set the ",(0,a.jsx)(n.code,{children:"allowUnsecureRandom"})," property in the ",(0,a.jsx)(n.code,{children:"AuthConfig"})," to ",(0,a.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"auth.AuthConfig.set(auth.AuthConfig(\n allowUnsecureRandom: true,\n));\n"})}),"\n",(0,a.jsx)(n.h2,{id:"updates-to-serialization-in-serverpod-20",children:"Updates to Serialization in Serverpod 2.0"}),"\n",(0,a.jsx)(n.h3,{id:"general-changes-to-model-serialization",children:"General Changes to Model Serialization"}),"\n",(0,a.jsxs)(n.p,{children:["Serverpod 2.0 significantly streamlines the model serialization process. In earlier versions, the ",(0,a.jsx)(n.code,{children:"fromJson"})," factory constructors needed a ",(0,a.jsx)(n.code,{children:"serializationManager"})," parameter to handle object deserialization. This parameter has now been removed, enhancing simplicity and usability."]}),"\n",(0,a.jsx)(n.h4,{id:"before-change",children:"Before change"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final Map json = classInstance.toJson();\nfinal SerializationManager serializationManager = Protocol();\nfinal ClassName test = ClassName.fromJson(json, serializationManager);\n"})}),"\n",(0,a.jsx)(n.h4,{id:"after-change",children:"After change"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final Map json = classInstance.toJson();\nfinal ClassName test = ClassName.fromJson(json);\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enhancements-for-custom-serialization",children:"Enhancements for Custom Serialization"}),"\n",(0,a.jsxs)(n.p,{children:["The removal of the ",(0,a.jsx)(n.code,{children:"serializationManager"})," parameter in Serverpod 2.0 simplifies the serialization process not only for general models but also significantly enhances custom serialization workflows.\nFor custom classes that previously utilized unique serialization logic with the ",(0,a.jsx)(n.code,{children:"serializationManager"}),", adjustments may be necessary."]}),"\n",(0,a.jsx)(n.h4,{id:"previous-implementation",children:"Previous Implementation"}),"\n",(0,a.jsxs)(n.p,{children:["In the previous versions, models required the ",(0,a.jsx)(n.code,{children:"serializationManager"})," to be passed explicitly, as shown in the following code snippet:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"factory ClassName.fromJson(\n Map json,\n SerializationManager serializationManager,\n ) {\n return ClassName(\n json['name'],\n );\n }\n"})}),"\n",(0,a.jsx)(n.h4,{id:"updated-implementation",children:"Updated Implementation"}),"\n",(0,a.jsxs)(n.p,{children:["With the release of Serverpod 2.0, the ",(0,a.jsx)(n.code,{children:"fromJson"})," constructor has been simplified and the ",(0,a.jsx)(n.code,{children:"serializationManager"})," has been removed:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"factory ClassName.fromJson(\n Map json,\n ) {\n return ClassName(\n json['name'],\n );\n }\n"})}),"\n",(0,a.jsxs)(n.h2,{id:"deprecation-notice-for-serializableentity",children:["Deprecation Notice for ",(0,a.jsx)(n.code,{children:"SerializableEntity"})]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"SerializableEntity"})," class is deprecated and will be removed in version 2.1. Please implement the ",(0,a.jsx)(n.code,{children:"SerializableModel"})," interface instead for creating serializable models."]}),"\n",(0,a.jsx)(n.h3,{id:"migration-guide",children:"Migration Guide"}),"\n",(0,a.jsxs)(n.p,{children:["To migrate your code from ",(0,a.jsx)(n.code,{children:"SerializableEntity"})," to ",(0,a.jsx)(n.code,{children:"SerializableModel"}),", replace ",(0,a.jsx)(n.code,{children:"extends SerializableEntity"})," with ",(0,a.jsx)(n.code,{children:"implements SerializableModel"})," in your model classes."]}),"\n",(0,a.jsx)(n.h4,{id:"example",children:"Example"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Before:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"class CustomClass extends SerializableEntity {\n // Your code here\n}\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"After:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"class CustomClass implements SerializableModel {\n // Your code here\n}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const i={},s=a.createContext(i);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[76238],{16681:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>l});var a=t(74848),i=t(28453);const s={},r="Upgrade to 2.0",o={id:"upgrading/upgrade-to-two",title:"Upgrade to 2.0",description:"Changes to authentication",source:"@site/docs/08-upgrading/03-upgrade-to-two.md",sourceDirName:"08-upgrading",slug:"/upgrading/upgrade-to-two",permalink:"/next/upgrading/upgrade-to-two",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/docs/08-upgrading/03-upgrade-to-two.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Upgrade to 1.2",permalink:"/next/upgrading/upgrade-to-one-point-two"},next:{title:"Serverpod Insights",permalink:"/next/tools/insights"}},d={},l=[{value:"Changes to authentication",id:"changes-to-authentication",level:2},{value:"Advanced integrations",id:"advanced-integrations",level:3},{value:"Changes to the Session Object",id:"changes-to-the-session-object",level:2},{value:"Removed deprecated fields",id:"removed-deprecated-fields",level:3},{value:"Authenticated user information retrieval",id:"authenticated-user-information-retrieval",level:3},{value:"Authentication helpers",id:"authentication-helpers",level:3},{value:"Changes to database queries",id:"changes-to-database-queries",level:2},{value:"Removed unsafeQueryMappedResults(...)",id:"removed-unsafequerymappedresults",level:3},{value:"Update return type for delete operations",id:"update-return-type-for-delete-operations",level:3},{value:"Changes to database tables",id:"changes-to-database-tables",level:2},{value:"Integer representation changed to bigint",id:"integer-representation-changed-to-bigint",level:3},{value:"Why is this change made?",id:"why-is-this-change-made",level:4},{value:"Ensuring new databases are created with the new representation",id:"ensuring-new-databases-are-created-with-the-new-representation",level:4},{value:"Migration of existing tables",id:"migration-of-existing-tables",level:4},{value:"Small tables",id:"small-tables",level:5},{value:"Large tables",id:"large-tables",level:5},{value:"Changes in the authentication module",id:"changes-in-the-authentication-module",level:2},{value:"Unsecure random disabled by default",id:"unsecure-random-disabled-by-default",level:3},{value:"Updates to Serialization in Serverpod 2.0",id:"updates-to-serialization-in-serverpod-20",level:2},{value:"General Changes to Model Serialization",id:"general-changes-to-model-serialization",level:3},{value:"Before change",id:"before-change",level:4},{value:"After change",id:"after-change",level:4},{value:"Enhancements for Custom Serialization",id:"enhancements-for-custom-serialization",level:3},{value:"Previous Implementation",id:"previous-implementation",level:4},{value:"Updated Implementation",id:"updated-implementation",level:4},{value:"Deprecation Notice for SerializableEntity",id:"deprecation-notice-for-serializableentity",level:2},{value:"Migration Guide",id:"migration-guide",level:3},{value:"Example",id:"example",level:4}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"upgrade-to-20",children:"Upgrade to 2.0"})}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-authentication",children:"Changes to authentication"}),"\n",(0,a.jsxs)(n.p,{children:["The base auth implementation has been removed from Serverpod core and moved into the ",(0,a.jsx)(n.code,{children:"serverpod_auth"})," package. If you are not using authentication at all this change does not impact you. If you are using the auth module already the transition is simple."]}),"\n",(0,a.jsxs)(n.p,{children:["The default authentication handler will now throw an ",(0,a.jsx)(n.code,{children:"UnimplementedError"}),". It is now required to supply the authentication handler to the Serverpod object, in your server.dart file make the following change:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"import 'package:serverpod_auth_server/serverpod_auth_server.dart' as auth;\n\nvoid run(List args) async {\n var pod = Serverpod(\n args,\n Protocol(),\n Endpoints(),\n authenticationHandler: auth.authenticationHandler, // Add this line\n );\n\n ...\n}\n"})}),"\n",(0,a.jsx)(n.h3,{id:"advanced-integrations",children:"Advanced integrations"}),"\n",(0,a.jsxs)(n.p,{children:["The methods ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," now takes the session object as a param and is no longer available on the session object. Instead import the class ",(0,a.jsx)(n.code,{children:"UserAuthentication"})," from the auth module to access these static methods."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"UserAuthentication.signInUser(session, userId, 'provider');\n\nUserAuthentication.signOutUser(session);\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The table ",(0,a.jsx)(n.code,{children:"serverpod_auth_key"})," has been removed from Serverpod core but is available in the serverpod_auth module instead. This means that if you wrote a custom integration before without using the serverpod_auth module you have to take care of managing your token implementation."]}),"\n",(0,a.jsxs)(n.p,{children:["Adding the definition of the ",(0,a.jsx)(n.code,{children:"serverpod_auth_key"})," table to your project is the simplest way to do a seamless migration."]}),"\n",(0,a.jsx)(n.p,{children:"The table was defined in the following way:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"### Provides a method of access for a user to authenticate with the server.\nclass: AuthKey\ntable: serverpod_auth_key\nfields:\n ### The id of the user to provide access to.\n userId: int\n\n ### The hashed version of the key.\n hash: String\n\n ### The key sent to the server to authenticate.\n key: String?, !persist\n\n ### The scopes this key provides access to.\n scopeNames: List\n\n ### The method of signing in this key was generated through. This can be email\n ### or different social logins.\n method: String\nindexes:\n serverpod_auth_key_userId_idx:\n fields: userId\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Your are then responsible for creating/removing entries in this table, the old ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," that used to provide this functionality can be found ",(0,a.jsx)(n.a,{href:"https://github.com/serverpod/serverpod/blob/13795a7bd4c0cc5a03101b6f378cb914673046dd/packages/serverpod/lib/src/server/session.dart#L359-L394",children:"here"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-the-session-object",children:"Changes to the Session Object"}),"\n",(0,a.jsx)(n.h3,{id:"removed-deprecated-fields",children:"Removed deprecated fields"}),"\n",(0,a.jsxs)(n.p,{children:["With Serverpod 2.0, we have removed the deprecated legacy database layer from the ",(0,a.jsx)(n.code,{children:"Session"})," object. The ",(0,a.jsx)(n.code,{children:"Session"})," object now incorporates the new database layer, accessed via the ",(0,a.jsx)(n.code,{children:"dbNext"})," field in Serverpod 1.2, under the ",(0,a.jsx)(n.code,{children:"db"})," field."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"session.dbNext.find(...);\n"})}),"\n",(0,a.jsx)(n.p,{children:"becomes"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"session.db.find(...);\n"})}),"\n",(0,a.jsx)(n.h3,{id:"authenticated-user-information-retrieval",children:"Authenticated user information retrieval"}),"\n",(0,a.jsxs)(n.p,{children:["In Serverpod 2.0, we have removed the getters ",(0,a.jsx)(n.code,{children:"scopes"})," and ",(0,a.jsx)(n.code,{children:"authenticatedUser"})," from session. This information is now retrievable through the ",(0,a.jsx)(n.code,{children:"authenticated"})," getter as fields of the returned object."]}),"\n",(0,a.jsx)(n.p,{children:"Replace this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"int? userId = await session.auth.authenticatedUser;\n\nSet? scopes = await session.scopes;\n"})}),"\n",(0,a.jsx)(n.p,{children:"With this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final authenticated = await session.authenticated;\n\n//Read authenticated userId\nint? userId = authenticated?.userId;\n\n//Read scopes\nSet? scopes = authenticated?.scopes;\n"})}),"\n",(0,a.jsxs)(n.p,{children:["If the ",(0,a.jsx)(n.code,{children:"authenticated"})," property is set on the session it effectively means there is an authenticated user making the request."]}),"\n",(0,a.jsx)(n.h3,{id:"authentication-helpers",children:"Authentication helpers"}),"\n",(0,a.jsxs)(n.p,{children:["The field ",(0,a.jsx)(n.code,{children:"auth"})," has been removed and the methods ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," have been moved to the ",(0,a.jsx)(n.code,{children:"serverpod_auth"})," module."]}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-database-queries",children:"Changes to database queries"}),"\n",(0,a.jsx)(n.h3,{id:"removed-unsafequerymappedresults",children:"Removed unsafeQueryMappedResults(...)"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," method has been removed. A similar result can now instead be formatted from the ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," result by calling the ",(0,a.jsx)(n.code,{children:"toColumnMap()"})," method for each row of the result. ",(0,a.jsx)(n.code,{children:"toColumnMap"})," returns a map containing the query alias for the column as key and the row-column value as value."]}),"\n",(0,a.jsx)(n.p,{children:"Given a query that performs a join like this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'SELECT\n "company"."id" AS "company.id",\n "company"."name" AS "company.name",\n "company"."townId" AS "company.townId",\n "company_town_town"."id" AS "company_town_town.id",\n "company_town_town"."name" AS "company_town_town.name",\n "company_town_town"."mayorId" AS "company_town_town.mayorId"\nFROM\n "company"\nLEFT JOIN\n "town" AS "company_town_town" ON "company"."townId" = "company_town_town"."id"\nORDER BY\n "company"."name"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The return type from ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," in 1.2 was:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company": {\n "company.id": 40,\n "company.name": "Apple",\n "company.townId": 64\n },\n "town": {\n "company_town_town.id": 64,\n "company_town_town.name": "San Francisco",\n "company_town_town.mayorId": null\n }\n },\n {\n "company": {\n "company.id": 39,\n "company.name": "Serverpod",\n "company.townId": 63\n },\n "town": {\n "company_town_town.id": 63,\n "company_town_town.name": "Stockholm",\n "company_town_town.mayorId": null\n }\n }\n]\n'})}),"\n",(0,a.jsxs)(n.p,{children:["And if ",(0,a.jsx)(n.code,{children:"result.map((row) => row.toColumnMap())"})," is used to format the result from ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," in 2.0, the following result is obtained:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company.id": 38,\n "company.name": "Apple",\n "company.townId": 62,\n "company_town_town.id": 62,\n "company_town_town.name": "San Francisco",\n "company_town_town.mayorId": null\n },\n {\n "company.id": 37,\n "company.name": "Serverpod",\n "company.townId": 61,\n "company_town_town.id": 61,\n "company_town_town.name": "Stockholm",\n "company_town_town.mayorId": null\n }\n]\n'})}),"\n",(0,a.jsx)(n.p,{children:"or for a simple query without aliases:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'SELECT\n "id",\n "name",\n "townId"\nFROM\n "company"\nORDER BY\n "name"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["the return type from ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," in 1.2 was:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company": {\n "id": 54,\n "name": "Apple",\n "townId": 86\n }\n },\n {\n "company": {\n "id": 53,\n "name": "Serverpod",\n "townId": 85\n }\n }\n]\n'})}),"\n",(0,a.jsxs)(n.p,{children:["and if ",(0,a.jsx)(n.code,{children:"result.map((row) => row.toColumnMap())"})," is used to format the result from ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," in 2.0, the following result is obtained:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:' [\n {\n "id": 54,\n "name": "Apple",\n "townId": 86\n },\n {\n "id": 53,\n "name": "Serverpod",\n "townId": 85\n }\n]\n'})}),"\n",(0,a.jsx)(n.h3,{id:"update-return-type-for-delete-operations",children:"Update return type for delete operations"}),"\n",(0,a.jsxs)(n.p,{children:["The return type for all delete operations has been changed from the ",(0,a.jsx)(n.code,{children:"id"})," of the deleted rows to the actual deleted rows. This makes the return type for the delete operations consistent with the return type of the other database operations. It also dramatically simplifies retrieving and removing rows in concurrent environments."]}),"\n",(0,a.jsx)(n.p,{children:"Return type before the change:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"int companyId = await Company.db.deleteRow(session, company);\nList companyIds = await Company.db.delete(session, [company]);\nList companyIds = await Company.db.deleteWhere(session, where: (t) => t.name.like('%Ltd'));\n"})}),"\n",(0,a.jsx)(n.p,{children:"Return types after the change:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"Company company = await Company.db.deleteRow(session, company);\nList companies = await Company.db.delete(session, [company]);\nList companies = await Company.db.deleteWhere(session, where: (t) => t.name.like('%Ltd'));\n"})}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-database-tables",children:"Changes to database tables"}),"\n",(0,a.jsx)(n.h3,{id:"integer-representation-changed-to-bigint",children:"Integer representation changed to bigint"}),"\n",(0,a.jsxs)(n.p,{children:["Integer representation in the database has changed from ",(0,a.jsx)(n.code,{children:"int"})," to ",(0,a.jsx)(n.code,{children:"bigint"}),". From now on, models with ",(0,a.jsx)(n.code,{children:"int"})," fields will generate database migrations where that field is defined as a ",(0,a.jsx)(n.code,{children:"bigint"})," type in the database."]}),"\n",(0,a.jsxs)(n.p,{children:["This change also applies to the ",(0,a.jsx)(n.code,{children:"id"})," field of models where ",(0,a.jsx)(n.code,{children:"bigserial"})," is now used to generate the id."]}),"\n",(0,a.jsx)(n.p,{children:"The change is compatible with existing databases. Existing migrations therefore, won't be changed by the Serverpod migration system. No manual modification to the database is required if this data representation is not essential for the application. However, all new migrations will be created with the new representation."}),"\n",(0,a.jsx)(n.h4,{id:"why-is-this-change-made",children:"Why is this change made?"}),"\n",(0,a.jsxs)(n.p,{children:["The change was made to ensure that ",(0,a.jsx)(n.a,{href:"https://dart.dev/guides/language/numbers",children:"Dart"})," and the database representation of integers is consistent. Dart uses 64-bit integers, and the ",(0,a.jsx)(n.code,{children:"int"})," type in Dart is a 64-bit integer. The ",(0,a.jsx)(n.code,{children:"int"})," type in PostgreSQL is a 32-bit integer. This means that the ",(0,a.jsx)(n.code,{children:"int"})," type in Dart can represent larger numbers than the ",(0,a.jsx)(n.code,{children:"int"})," type in PostgreSQL. By using ",(0,a.jsx)(n.code,{children:"bigint"})," in PostgreSQL, the integer representation is consistent between Dart and the database."]}),"\n",(0,a.jsxs)(n.p,{children:["In terms of performance, there are usually no significant drawbacks with using ",(0,a.jsx)(n.code,{children:"bigint"})," instead of ",(0,a.jsx)(n.code,{children:"int"}),". In most cases a good index strategy will be more important than the integer representation. Here is a guide that benchmarks the performance of ",(0,a.jsx)(n.code,{children:"int"})," and ",(0,a.jsx)(n.code,{children:"bigint"})," in PostgreSQL: ",(0,a.jsx)(n.a,{href:"https://blog.rustprooflabs.com/2021/06/postgres-bigint-by-default",children:"Use BIGINT in Postgres"})]}),"\n",(0,a.jsx)(n.h4,{id:"ensuring-new-databases-are-created-with-the-new-representation",children:"Ensuring new databases are created with the new representation"}),"\n",(0,a.jsxs)(n.p,{children:["Since existing migrations won't be changed, databases that are created with these will still use ",(0,a.jsx)(n.code,{children:"int"})," to represent integers."]}),"\n",(0,a.jsx)(n.p,{children:"To ensure new databases are created with the new representation, the latest migration should be generated using Serverpod 2.0. It is enough to have an empty migration to ensure new databases use the new representation."}),"\n",(0,a.jsx)(n.p,{children:"A new empty migration can be created by running the following command in the terminal:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"$ serverpod create-migration --force\n"})}),"\n",(0,a.jsx)(n.h4,{id:"migration-of-existing-tables",children:"Migration of existing tables"}),"\n",(0,a.jsx)(n.p,{children:"The migration of existing tables to use the new representation will vary depending on the database content. Utilizing the wrong migration strategy might cause downtime for your application. That is the reason Serverpod does not automatically migrate existing tables."}),"\n",(0,a.jsx)(n.h5,{id:"small-tables",children:"Small tables"}),"\n",(0,a.jsx)(n.p,{children:"A simple way to migrate for small tables is to execute the following sql query to the database:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'ALTER SEQUENCE "my_table_id_seq" AS bigint;\nALTER TABLE "my_table" ALTER "id" TYPE bigint;\nALTER TABLE "my_table" ALTER "myNumber" TYPE bigint;\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The first two lines modify the id sequence for a table named ",(0,a.jsx)(n.code,{children:'"my_table"'})," to use ",(0,a.jsx)(n.code,{children:"bigint"})," instead of ",(0,a.jsx)(n.code,{children:"int"}),". The last line modifies a column of the same table to use ",(0,a.jsx)(n.code,{children:"bigint"}),". The drawback of this approach is that it locks the table during the migration. Therefore, this strategy is not recommended for large tables."]}),"\n",(0,a.jsx)(n.h5,{id:"large-tables",children:"Large tables"}),"\n",(0,a.jsx)(n.p,{children:"Migrating large tables without application downtime is a more complex operation, and the approach will vary depending on the data structure. Below are some gathered resources on the subject."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"http://zemanta.github.io/2021/08/25/column-migration-from-int-to-bigint-in-postgresql/",children:"Zemata - Column migration from INT to BIGINT"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://am2.co/2019/12/changing-a-column-from-int-to-bigint-without-downtime/",children:"AM^2 - Changing a column from int to bigint, without downtime"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://www.crunchydata.com/blog/the-integer-at-the-end-of-the-universe-integer-overflow-in-postgres",children:"Crunch data - The integer at the End of the Universe"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"changes-in-the-authentication-module",children:"Changes in the authentication module"}),"\n",(0,a.jsx)(n.h3,{id:"unsecure-random-disabled-by-default",children:"Unsecure random disabled by default"}),"\n",(0,a.jsxs)(n.p,{children:["The authentication module's default value for allowing unsecure random number generation is now ",(0,a.jsx)(n.code,{children:"false"}),". An exception will be thrown when trying to hash a password if no secure random number generator is available. To preserve the old behavior and enable unsecure random number generation, set the ",(0,a.jsx)(n.code,{children:"allowUnsecureRandom"})," property in the ",(0,a.jsx)(n.code,{children:"AuthConfig"})," to ",(0,a.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"auth.AuthConfig.set(auth.AuthConfig(\n allowUnsecureRandom: true,\n));\n"})}),"\n",(0,a.jsx)(n.h2,{id:"updates-to-serialization-in-serverpod-20",children:"Updates to Serialization in Serverpod 2.0"}),"\n",(0,a.jsx)(n.h3,{id:"general-changes-to-model-serialization",children:"General Changes to Model Serialization"}),"\n",(0,a.jsxs)(n.p,{children:["Serverpod 2.0 significantly streamlines the model serialization process. In earlier versions, the ",(0,a.jsx)(n.code,{children:"fromJson"})," factory constructors needed a ",(0,a.jsx)(n.code,{children:"serializationManager"})," parameter to handle object deserialization. This parameter has now been removed, enhancing simplicity and usability."]}),"\n",(0,a.jsx)(n.h4,{id:"before-change",children:"Before change"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final Map json = classInstance.toJson();\nfinal SerializationManager serializationManager = Protocol();\nfinal ClassName test = ClassName.fromJson(json, serializationManager);\n"})}),"\n",(0,a.jsx)(n.h4,{id:"after-change",children:"After change"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final Map json = classInstance.toJson();\nfinal ClassName test = ClassName.fromJson(json);\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enhancements-for-custom-serialization",children:"Enhancements for Custom Serialization"}),"\n",(0,a.jsxs)(n.p,{children:["The removal of the ",(0,a.jsx)(n.code,{children:"serializationManager"})," parameter in Serverpod 2.0 simplifies the serialization process not only for general models but also significantly enhances custom serialization workflows.\nFor custom classes that previously utilized unique serialization logic with the ",(0,a.jsx)(n.code,{children:"serializationManager"}),", adjustments may be necessary."]}),"\n",(0,a.jsx)(n.h4,{id:"previous-implementation",children:"Previous Implementation"}),"\n",(0,a.jsxs)(n.p,{children:["In the previous versions, models required the ",(0,a.jsx)(n.code,{children:"serializationManager"})," to be passed explicitly, as shown in the following code snippet:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"factory ClassName.fromJson(\n Map json,\n SerializationManager serializationManager,\n ) {\n return ClassName(\n json['name'],\n );\n }\n"})}),"\n",(0,a.jsx)(n.h4,{id:"updated-implementation",children:"Updated Implementation"}),"\n",(0,a.jsxs)(n.p,{children:["With the release of Serverpod 2.0, the ",(0,a.jsx)(n.code,{children:"fromJson"})," constructor has been simplified and the ",(0,a.jsx)(n.code,{children:"serializationManager"})," has been removed:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"factory ClassName.fromJson(\n Map json,\n ) {\n return ClassName(\n json['name'],\n );\n }\n"})}),"\n",(0,a.jsxs)(n.h2,{id:"deprecation-notice-for-serializableentity",children:["Deprecation Notice for ",(0,a.jsx)(n.code,{children:"SerializableEntity"})]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"SerializableEntity"})," class is deprecated and will be removed in version 3. Please implement the ",(0,a.jsx)(n.code,{children:"SerializableModel"})," interface instead for creating serializable models."]}),"\n",(0,a.jsx)(n.h3,{id:"migration-guide",children:"Migration Guide"}),"\n",(0,a.jsxs)(n.p,{children:["To migrate your code from ",(0,a.jsx)(n.code,{children:"SerializableEntity"})," to ",(0,a.jsx)(n.code,{children:"SerializableModel"}),", replace ",(0,a.jsx)(n.code,{children:"extends SerializableEntity"})," with ",(0,a.jsx)(n.code,{children:"implements SerializableModel"})," in your model classes."]}),"\n",(0,a.jsx)(n.h4,{id:"example",children:"Example"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Before:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"class CustomClass extends SerializableEntity {\n // Your code here\n}\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"After:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"class CustomClass implements SerializableModel {\n // Your code here\n}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const i={},s=a.createContext(i);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/ac5db01d.433c50c6.js b/docs/assets/js/ac5db01d.bf926c46.js similarity index 93% rename from docs/assets/js/ac5db01d.433c50c6.js rename to docs/assets/js/ac5db01d.bf926c46.js index 17b58d5bb..f36c102a8 100644 --- a/docs/assets/js/ac5db01d.433c50c6.js +++ b/docs/assets/js/ac5db01d.bf926c46.js @@ -1 +1 @@ -"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[97785],{56458:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>l});var a=t(74848),i=t(28453);const s={},r="Upgrade to 2.0",o={id:"upgrading/upgrade-to-two",title:"Upgrade to 2.0",description:"Changes to authentication",source:"@site/versioned_docs/version-2.1.0/08-upgrading/03-upgrade-to-two.md",sourceDirName:"08-upgrading",slug:"/upgrading/upgrade-to-two",permalink:"/upgrading/upgrade-to-two",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/versioned_docs/version-2.1.0/08-upgrading/03-upgrade-to-two.md",tags:[],version:"2.1.0",sidebarPosition:3,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Upgrade to 1.2",permalink:"/upgrading/upgrade-to-one-point-two"},next:{title:"Serverpod Insights",permalink:"/tools/insights"}},d={},l=[{value:"Changes to authentication",id:"changes-to-authentication",level:2},{value:"Advanced integrations",id:"advanced-integrations",level:3},{value:"Changes to the Session Object",id:"changes-to-the-session-object",level:2},{value:"Removed deprecated fields",id:"removed-deprecated-fields",level:3},{value:"Authenticated user information retrieval",id:"authenticated-user-information-retrieval",level:3},{value:"Authentication helpers",id:"authentication-helpers",level:3},{value:"Changes to database queries",id:"changes-to-database-queries",level:2},{value:"Removed unsafeQueryMappedResults(...)",id:"removed-unsafequerymappedresults",level:3},{value:"Update return type for delete operations",id:"update-return-type-for-delete-operations",level:3},{value:"Changes to database tables",id:"changes-to-database-tables",level:2},{value:"Integer representation changed to bigint",id:"integer-representation-changed-to-bigint",level:3},{value:"Why is this change made?",id:"why-is-this-change-made",level:4},{value:"Ensuring new databases are created with the new representation",id:"ensuring-new-databases-are-created-with-the-new-representation",level:4},{value:"Migration of existing tables",id:"migration-of-existing-tables",level:4},{value:"Small tables",id:"small-tables",level:5},{value:"Large tables",id:"large-tables",level:5},{value:"Changes in the authentication module",id:"changes-in-the-authentication-module",level:2},{value:"Unsecure random disabled by default",id:"unsecure-random-disabled-by-default",level:3},{value:"Updates to Serialization in Serverpod 2.0",id:"updates-to-serialization-in-serverpod-20",level:2},{value:"General Changes to Model Serialization",id:"general-changes-to-model-serialization",level:3},{value:"Before change",id:"before-change",level:4},{value:"After change",id:"after-change",level:4},{value:"Enhancements for Custom Serialization",id:"enhancements-for-custom-serialization",level:3},{value:"Previous Implementation",id:"previous-implementation",level:4},{value:"Updated Implementation",id:"updated-implementation",level:4},{value:"Deprecation Notice for SerializableEntity",id:"deprecation-notice-for-serializableentity",level:2},{value:"Migration Guide",id:"migration-guide",level:3},{value:"Example",id:"example",level:4}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"upgrade-to-20",children:"Upgrade to 2.0"})}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-authentication",children:"Changes to authentication"}),"\n",(0,a.jsxs)(n.p,{children:["The base auth implementation has been removed from Serverpod core and moved into the ",(0,a.jsx)(n.code,{children:"serverpod_auth"})," package. If you are not using authentication at all this change does not impact you. If you are using the auth module already the transition is simple."]}),"\n",(0,a.jsxs)(n.p,{children:["The default authentication handler will now throw an ",(0,a.jsx)(n.code,{children:"UnimplementedError"}),". It is now required to supply the authentication handler to the Serverpod object, in your server.dart file make the following change:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"import 'package:serverpod_auth_server/serverpod_auth_server.dart' as auth;\n\nvoid run(List args) async {\n var pod = Serverpod(\n args,\n Protocol(),\n Endpoints(),\n authenticationHandler: auth.authenticationHandler, // Add this line\n );\n\n ...\n}\n"})}),"\n",(0,a.jsx)(n.h3,{id:"advanced-integrations",children:"Advanced integrations"}),"\n",(0,a.jsxs)(n.p,{children:["The methods ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," now takes the session object as a param and is no longer available on the session object. Instead import the class ",(0,a.jsx)(n.code,{children:"UserAuthentication"})," from the auth module to access these static methods."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"UserAuthentication.signInUser(session, userId, 'provider');\n\nUserAuthentication.signOutUser(session);\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The table ",(0,a.jsx)(n.code,{children:"serverpod_auth_key"})," has been removed from Serverpod core but is available in the serverpod_auth module instead. This means that if you wrote a custom integration before without using the serverpod_auth module you have to take care of managing your token implementation."]}),"\n",(0,a.jsxs)(n.p,{children:["Adding the definition of the ",(0,a.jsx)(n.code,{children:"serverpod_auth_key"})," table to your project is the simplest way to do a seamless migration."]}),"\n",(0,a.jsx)(n.p,{children:"The table was defined in the following way:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"### Provides a method of access for a user to authenticate with the server.\nclass: AuthKey\ntable: serverpod_auth_key\nfields:\n ### The id of the user to provide access to.\n userId: int\n\n ### The hashed version of the key.\n hash: String\n\n ### The key sent to the server to authenticate.\n key: String?, !persist\n\n ### The scopes this key provides access to.\n scopeNames: List\n\n ### The method of signing in this key was generated through. This can be email\n ### or different social logins.\n method: String\nindexes:\n serverpod_auth_key_userId_idx:\n fields: userId\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Your are then responsible for creating/removing entries in this table, the old ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," that used to provide this functionality can be found ",(0,a.jsx)(n.a,{href:"https://github.com/serverpod/serverpod/blob/13795a7bd4c0cc5a03101b6f378cb914673046dd/packages/serverpod/lib/src/server/session.dart#L359-L394",children:"here"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-the-session-object",children:"Changes to the Session Object"}),"\n",(0,a.jsx)(n.h3,{id:"removed-deprecated-fields",children:"Removed deprecated fields"}),"\n",(0,a.jsxs)(n.p,{children:["With Serverpod 2.0, we have removed the deprecated legacy database layer from the ",(0,a.jsx)(n.code,{children:"Session"})," object. The ",(0,a.jsx)(n.code,{children:"Session"})," object now incorporates the new database layer, accessed via the ",(0,a.jsx)(n.code,{children:"dbNext"})," field in Serverpod 1.2, under the ",(0,a.jsx)(n.code,{children:"db"})," field."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"session.dbNext.find(...);\n"})}),"\n",(0,a.jsx)(n.p,{children:"becomes"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"session.db.find(...);\n"})}),"\n",(0,a.jsx)(n.h3,{id:"authenticated-user-information-retrieval",children:"Authenticated user information retrieval"}),"\n",(0,a.jsxs)(n.p,{children:["In Serverpod 2.0, we have removed the getters ",(0,a.jsx)(n.code,{children:"scopes"})," and ",(0,a.jsx)(n.code,{children:"authenticatedUser"})," from session. This information is now retrievable through the ",(0,a.jsx)(n.code,{children:"authenticated"})," getter as fields of the returned object."]}),"\n",(0,a.jsx)(n.p,{children:"Replace this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"int? userId = await session.auth.authenticatedUser;\n\nSet? scopes = await session.scopes;\n"})}),"\n",(0,a.jsx)(n.p,{children:"With this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final authenticated = await session.authenticated;\n\n//Read authenticated userId\nint? userId = authenticated?.userId;\n\n//Read scopes\nSet? scopes = authenticated?.scopes;\n"})}),"\n",(0,a.jsxs)(n.p,{children:["If the ",(0,a.jsx)(n.code,{children:"authenticated"})," property is set on the session it effectively means there is an authenticated user making the request."]}),"\n",(0,a.jsx)(n.h3,{id:"authentication-helpers",children:"Authentication helpers"}),"\n",(0,a.jsxs)(n.p,{children:["The field ",(0,a.jsx)(n.code,{children:"auth"})," has been removed and the methods ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," have been moved to the ",(0,a.jsx)(n.code,{children:"serverpod_auth"})," module."]}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-database-queries",children:"Changes to database queries"}),"\n",(0,a.jsx)(n.h3,{id:"removed-unsafequerymappedresults",children:"Removed unsafeQueryMappedResults(...)"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," method has been removed. A similar result can now instead be formatted from the ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," result by calling the ",(0,a.jsx)(n.code,{children:"toColumnMap()"})," method for each row of the result. ",(0,a.jsx)(n.code,{children:"toColumnMap"})," returns a map containing the query alias for the column as key and the row-column value as value."]}),"\n",(0,a.jsx)(n.p,{children:"Given a query that performs a join like this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'SELECT\n "company"."id" AS "company.id",\n "company"."name" AS "company.name",\n "company"."townId" AS "company.townId",\n "company_town_town"."id" AS "company_town_town.id",\n "company_town_town"."name" AS "company_town_town.name",\n "company_town_town"."mayorId" AS "company_town_town.mayorId"\nFROM\n "company"\nLEFT JOIN\n "town" AS "company_town_town" ON "company"."townId" = "company_town_town"."id"\nORDER BY\n "company"."name"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The return type from ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," in 1.2 was:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company": {\n "company.id": 40,\n "company.name": "Apple",\n "company.townId": 64\n },\n "town": {\n "company_town_town.id": 64,\n "company_town_town.name": "San Francisco",\n "company_town_town.mayorId": null\n }\n },\n {\n "company": {\n "company.id": 39,\n "company.name": "Serverpod",\n "company.townId": 63\n },\n "town": {\n "company_town_town.id": 63,\n "company_town_town.name": "Stockholm",\n "company_town_town.mayorId": null\n }\n }\n]\n'})}),"\n",(0,a.jsxs)(n.p,{children:["And if ",(0,a.jsx)(n.code,{children:"result.map((row) => row.toColumnMap())"})," is used to format the result from ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," in 2.0, the following result is obtained:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company.id": 38,\n "company.name": "Apple",\n "company.townId": 62,\n "company_town_town.id": 62,\n "company_town_town.name": "San Francisco",\n "company_town_town.mayorId": null\n },\n {\n "company.id": 37,\n "company.name": "Serverpod",\n "company.townId": 61,\n "company_town_town.id": 61,\n "company_town_town.name": "Stockholm",\n "company_town_town.mayorId": null\n }\n]\n'})}),"\n",(0,a.jsx)(n.p,{children:"or for a simple query without aliases:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'SELECT\n "id",\n "name",\n "townId"\nFROM\n "company"\nORDER BY\n "name"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["the return type from ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," in 1.2 was:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company": {\n "id": 54,\n "name": "Apple",\n "townId": 86\n }\n },\n {\n "company": {\n "id": 53,\n "name": "Serverpod",\n "townId": 85\n }\n }\n]\n'})}),"\n",(0,a.jsxs)(n.p,{children:["and if ",(0,a.jsx)(n.code,{children:"result.map((row) => row.toColumnMap())"})," is used to format the result from ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," in 2.0, the following result is obtained:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:' [\n {\n "id": 54,\n "name": "Apple",\n "townId": 86\n },\n {\n "id": 53,\n "name": "Serverpod",\n "townId": 85\n }\n]\n'})}),"\n",(0,a.jsx)(n.h3,{id:"update-return-type-for-delete-operations",children:"Update return type for delete operations"}),"\n",(0,a.jsxs)(n.p,{children:["The return type for all delete operations has been changed from the ",(0,a.jsx)(n.code,{children:"id"})," of the deleted rows to the actual deleted rows. This makes the return type for the delete operations consistent with the return type of the other database operations. It also dramatically simplifies retrieving and removing rows in concurrent environments."]}),"\n",(0,a.jsx)(n.p,{children:"Return type before the change:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"int companyId = await Company.db.deleteRow(session, company);\nList companyIds = await Company.db.delete(session, [company]);\nList companyIds = await Company.db.deleteWhere(session, where: (t) => t.name.like('%Ltd'));\n"})}),"\n",(0,a.jsx)(n.p,{children:"Return types after the change:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"Company company = await Company.db.deleteRow(session, company);\nList companies = await Company.db.delete(session, [company]);\nList companies = await Company.db.deleteWhere(session, where: (t) => t.name.like('%Ltd'));\n"})}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-database-tables",children:"Changes to database tables"}),"\n",(0,a.jsx)(n.h3,{id:"integer-representation-changed-to-bigint",children:"Integer representation changed to bigint"}),"\n",(0,a.jsxs)(n.p,{children:["Integer representation in the database has changed from ",(0,a.jsx)(n.code,{children:"int"})," to ",(0,a.jsx)(n.code,{children:"bigint"}),". From now on, models with ",(0,a.jsx)(n.code,{children:"int"})," fields will generate database migrations where that field is defined as a ",(0,a.jsx)(n.code,{children:"bigint"})," type in the database."]}),"\n",(0,a.jsxs)(n.p,{children:["This change also applies to the ",(0,a.jsx)(n.code,{children:"id"})," field of models where ",(0,a.jsx)(n.code,{children:"bigserial"})," is now used to generate the id."]}),"\n",(0,a.jsx)(n.p,{children:"The change is compatible with existing databases. Existing migrations therefore, won't be changed by the Serverpod migration system. No manual modification to the database is required if this data representation is not essential for the application. However, all new migrations will be created with the new representation."}),"\n",(0,a.jsx)(n.h4,{id:"why-is-this-change-made",children:"Why is this change made?"}),"\n",(0,a.jsxs)(n.p,{children:["The change was made to ensure that ",(0,a.jsx)(n.a,{href:"https://dart.dev/guides/language/numbers",children:"Dart"})," and the database representation of integers is consistent. Dart uses 64-bit integers, and the ",(0,a.jsx)(n.code,{children:"int"})," type in Dart is a 64-bit integer. The ",(0,a.jsx)(n.code,{children:"int"})," type in PostgreSQL is a 32-bit integer. This means that the ",(0,a.jsx)(n.code,{children:"int"})," type in Dart can represent larger numbers than the ",(0,a.jsx)(n.code,{children:"int"})," type in PostgreSQL. By using ",(0,a.jsx)(n.code,{children:"bigint"})," in PostgreSQL, the integer representation is consistent between Dart and the database."]}),"\n",(0,a.jsxs)(n.p,{children:["In terms of performance, there are usually no significant drawbacks with using ",(0,a.jsx)(n.code,{children:"bigint"})," instead of ",(0,a.jsx)(n.code,{children:"int"}),". In most cases a good index strategy will be more important than the integer representation. Here is a guide that benchmarks the performance of ",(0,a.jsx)(n.code,{children:"int"})," and ",(0,a.jsx)(n.code,{children:"bigint"})," in PostgreSQL: ",(0,a.jsx)(n.a,{href:"https://blog.rustprooflabs.com/2021/06/postgres-bigint-by-default",children:"Use BIGINT in Postgres"})]}),"\n",(0,a.jsx)(n.h4,{id:"ensuring-new-databases-are-created-with-the-new-representation",children:"Ensuring new databases are created with the new representation"}),"\n",(0,a.jsxs)(n.p,{children:["Since existing migrations won't be changed, databases that are created with these will still use ",(0,a.jsx)(n.code,{children:"int"})," to represent integers."]}),"\n",(0,a.jsx)(n.p,{children:"To ensure new databases are created with the new representation, the latest migration should be generated using Serverpod 2.0. It is enough to have an empty migration to ensure new databases use the new representation."}),"\n",(0,a.jsx)(n.p,{children:"A new empty migration can be created by running the following command in the terminal:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"$ serverpod create-migration --force\n"})}),"\n",(0,a.jsx)(n.h4,{id:"migration-of-existing-tables",children:"Migration of existing tables"}),"\n",(0,a.jsx)(n.p,{children:"The migration of existing tables to use the new representation will vary depending on the database content. Utilizing the wrong migration strategy might cause downtime for your application. That is the reason Serverpod does not automatically migrate existing tables."}),"\n",(0,a.jsx)(n.h5,{id:"small-tables",children:"Small tables"}),"\n",(0,a.jsx)(n.p,{children:"A simple way to migrate for small tables is to execute the following sql query to the database:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'ALTER SEQUENCE "my_table_id_seq" AS bigint;\nALTER TABLE "my_table" ALTER "id" TYPE bigint;\nALTER TABLE "my_table" ALTER "myNumber" TYPE bigint;\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The first two lines modify the id sequence for a table named ",(0,a.jsx)(n.code,{children:'"my_table"'})," to use ",(0,a.jsx)(n.code,{children:"bigint"})," instead of ",(0,a.jsx)(n.code,{children:"int"}),". The last line modifies a column of the same table to use ",(0,a.jsx)(n.code,{children:"bigint"}),". The drawback of this approach is that it locks the table during the migration. Therefore, this strategy is not recommended for large tables."]}),"\n",(0,a.jsx)(n.h5,{id:"large-tables",children:"Large tables"}),"\n",(0,a.jsx)(n.p,{children:"Migrating large tables without application downtime is a more complex operation, and the approach will vary depending on the data structure. Below are some gathered resources on the subject."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"http://zemanta.github.io/2021/08/25/column-migration-from-int-to-bigint-in-postgresql/",children:"Zemata - Column migration from INT to BIGINT"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://am2.co/2019/12/changing-a-column-from-int-to-bigint-without-downtime/",children:"AM^2 - Changing a column from int to bigint, without downtime"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://www.crunchydata.com/blog/the-integer-at-the-end-of-the-universe-integer-overflow-in-postgres",children:"Crunch data - The integer at the End of the Universe"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"changes-in-the-authentication-module",children:"Changes in the authentication module"}),"\n",(0,a.jsx)(n.h3,{id:"unsecure-random-disabled-by-default",children:"Unsecure random disabled by default"}),"\n",(0,a.jsxs)(n.p,{children:["The authentication module's default value for allowing unsecure random number generation is now ",(0,a.jsx)(n.code,{children:"false"}),". An exception will be thrown when trying to hash a password if no secure random number generator is available. To preserve the old behavior and enable unsecure random number generation, set the ",(0,a.jsx)(n.code,{children:"allowUnsecureRandom"})," property in the ",(0,a.jsx)(n.code,{children:"AuthConfig"})," to ",(0,a.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"auth.AuthConfig.set(auth.AuthConfig(\n allowUnsecureRandom: true,\n));\n"})}),"\n",(0,a.jsx)(n.h2,{id:"updates-to-serialization-in-serverpod-20",children:"Updates to Serialization in Serverpod 2.0"}),"\n",(0,a.jsx)(n.h3,{id:"general-changes-to-model-serialization",children:"General Changes to Model Serialization"}),"\n",(0,a.jsxs)(n.p,{children:["Serverpod 2.0 significantly streamlines the model serialization process. In earlier versions, the ",(0,a.jsx)(n.code,{children:"fromJson"})," factory constructors needed a ",(0,a.jsx)(n.code,{children:"serializationManager"})," parameter to handle object deserialization. This parameter has now been removed, enhancing simplicity and usability."]}),"\n",(0,a.jsx)(n.h4,{id:"before-change",children:"Before change"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final Map json = classInstance.toJson();\nfinal SerializationManager serializationManager = Protocol();\nfinal ClassName test = ClassName.fromJson(json, serializationManager);\n"})}),"\n",(0,a.jsx)(n.h4,{id:"after-change",children:"After change"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final Map json = classInstance.toJson();\nfinal ClassName test = ClassName.fromJson(json);\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enhancements-for-custom-serialization",children:"Enhancements for Custom Serialization"}),"\n",(0,a.jsxs)(n.p,{children:["The removal of the ",(0,a.jsx)(n.code,{children:"serializationManager"})," parameter in Serverpod 2.0 simplifies the serialization process not only for general models but also significantly enhances custom serialization workflows.\nFor custom classes that previously utilized unique serialization logic with the ",(0,a.jsx)(n.code,{children:"serializationManager"}),", adjustments may be necessary."]}),"\n",(0,a.jsx)(n.h4,{id:"previous-implementation",children:"Previous Implementation"}),"\n",(0,a.jsxs)(n.p,{children:["In the previous versions, models required the ",(0,a.jsx)(n.code,{children:"serializationManager"})," to be passed explicitly, as shown in the following code snippet:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"factory ClassName.fromJson(\n Map json,\n SerializationManager serializationManager,\n ) {\n return ClassName(\n json['name'],\n );\n }\n"})}),"\n",(0,a.jsx)(n.h4,{id:"updated-implementation",children:"Updated Implementation"}),"\n",(0,a.jsxs)(n.p,{children:["With the release of Serverpod 2.0, the ",(0,a.jsx)(n.code,{children:"fromJson"})," constructor has been simplified and the ",(0,a.jsx)(n.code,{children:"serializationManager"})," has been removed:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"factory ClassName.fromJson(\n Map json,\n ) {\n return ClassName(\n json['name'],\n );\n }\n"})}),"\n",(0,a.jsxs)(n.h2,{id:"deprecation-notice-for-serializableentity",children:["Deprecation Notice for ",(0,a.jsx)(n.code,{children:"SerializableEntity"})]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"SerializableEntity"})," class is deprecated and will be removed in version 2.1. Please implement the ",(0,a.jsx)(n.code,{children:"SerializableModel"})," interface instead for creating serializable models."]}),"\n",(0,a.jsx)(n.h3,{id:"migration-guide",children:"Migration Guide"}),"\n",(0,a.jsxs)(n.p,{children:["To migrate your code from ",(0,a.jsx)(n.code,{children:"SerializableEntity"})," to ",(0,a.jsx)(n.code,{children:"SerializableModel"}),", replace ",(0,a.jsx)(n.code,{children:"extends SerializableEntity"})," with ",(0,a.jsx)(n.code,{children:"implements SerializableModel"})," in your model classes."]}),"\n",(0,a.jsx)(n.h4,{id:"example",children:"Example"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Before:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"class CustomClass extends SerializableEntity {\n // Your code here\n}\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"After:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"class CustomClass implements SerializableModel {\n // Your code here\n}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const i={},s=a.createContext(i);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[97785],{56458:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>l});var a=t(74848),i=t(28453);const s={},r="Upgrade to 2.0",o={id:"upgrading/upgrade-to-two",title:"Upgrade to 2.0",description:"Changes to authentication",source:"@site/versioned_docs/version-2.1.0/08-upgrading/03-upgrade-to-two.md",sourceDirName:"08-upgrading",slug:"/upgrading/upgrade-to-two",permalink:"/upgrading/upgrade-to-two",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/versioned_docs/version-2.1.0/08-upgrading/03-upgrade-to-two.md",tags:[],version:"2.1.0",sidebarPosition:3,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Upgrade to 1.2",permalink:"/upgrading/upgrade-to-one-point-two"},next:{title:"Serverpod Insights",permalink:"/tools/insights"}},d={},l=[{value:"Changes to authentication",id:"changes-to-authentication",level:2},{value:"Advanced integrations",id:"advanced-integrations",level:3},{value:"Changes to the Session Object",id:"changes-to-the-session-object",level:2},{value:"Removed deprecated fields",id:"removed-deprecated-fields",level:3},{value:"Authenticated user information retrieval",id:"authenticated-user-information-retrieval",level:3},{value:"Authentication helpers",id:"authentication-helpers",level:3},{value:"Changes to database queries",id:"changes-to-database-queries",level:2},{value:"Removed unsafeQueryMappedResults(...)",id:"removed-unsafequerymappedresults",level:3},{value:"Update return type for delete operations",id:"update-return-type-for-delete-operations",level:3},{value:"Changes to database tables",id:"changes-to-database-tables",level:2},{value:"Integer representation changed to bigint",id:"integer-representation-changed-to-bigint",level:3},{value:"Why is this change made?",id:"why-is-this-change-made",level:4},{value:"Ensuring new databases are created with the new representation",id:"ensuring-new-databases-are-created-with-the-new-representation",level:4},{value:"Migration of existing tables",id:"migration-of-existing-tables",level:4},{value:"Small tables",id:"small-tables",level:5},{value:"Large tables",id:"large-tables",level:5},{value:"Changes in the authentication module",id:"changes-in-the-authentication-module",level:2},{value:"Unsecure random disabled by default",id:"unsecure-random-disabled-by-default",level:3},{value:"Updates to Serialization in Serverpod 2.0",id:"updates-to-serialization-in-serverpod-20",level:2},{value:"General Changes to Model Serialization",id:"general-changes-to-model-serialization",level:3},{value:"Before change",id:"before-change",level:4},{value:"After change",id:"after-change",level:4},{value:"Enhancements for Custom Serialization",id:"enhancements-for-custom-serialization",level:3},{value:"Previous Implementation",id:"previous-implementation",level:4},{value:"Updated Implementation",id:"updated-implementation",level:4},{value:"Deprecation Notice for SerializableEntity",id:"deprecation-notice-for-serializableentity",level:2},{value:"Migration Guide",id:"migration-guide",level:3},{value:"Example",id:"example",level:4}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"upgrade-to-20",children:"Upgrade to 2.0"})}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-authentication",children:"Changes to authentication"}),"\n",(0,a.jsxs)(n.p,{children:["The base auth implementation has been removed from Serverpod core and moved into the ",(0,a.jsx)(n.code,{children:"serverpod_auth"})," package. If you are not using authentication at all this change does not impact you. If you are using the auth module already the transition is simple."]}),"\n",(0,a.jsxs)(n.p,{children:["The default authentication handler will now throw an ",(0,a.jsx)(n.code,{children:"UnimplementedError"}),". It is now required to supply the authentication handler to the Serverpod object, in your server.dart file make the following change:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"import 'package:serverpod_auth_server/serverpod_auth_server.dart' as auth;\n\nvoid run(List args) async {\n var pod = Serverpod(\n args,\n Protocol(),\n Endpoints(),\n authenticationHandler: auth.authenticationHandler, // Add this line\n );\n\n ...\n}\n"})}),"\n",(0,a.jsx)(n.h3,{id:"advanced-integrations",children:"Advanced integrations"}),"\n",(0,a.jsxs)(n.p,{children:["The methods ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," now takes the session object as a param and is no longer available on the session object. Instead import the class ",(0,a.jsx)(n.code,{children:"UserAuthentication"})," from the auth module to access these static methods."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"UserAuthentication.signInUser(session, userId, 'provider');\n\nUserAuthentication.signOutUser(session);\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The table ",(0,a.jsx)(n.code,{children:"serverpod_auth_key"})," has been removed from Serverpod core but is available in the serverpod_auth module instead. This means that if you wrote a custom integration before without using the serverpod_auth module you have to take care of managing your token implementation."]}),"\n",(0,a.jsxs)(n.p,{children:["Adding the definition of the ",(0,a.jsx)(n.code,{children:"serverpod_auth_key"})," table to your project is the simplest way to do a seamless migration."]}),"\n",(0,a.jsx)(n.p,{children:"The table was defined in the following way:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"### Provides a method of access for a user to authenticate with the server.\nclass: AuthKey\ntable: serverpod_auth_key\nfields:\n ### The id of the user to provide access to.\n userId: int\n\n ### The hashed version of the key.\n hash: String\n\n ### The key sent to the server to authenticate.\n key: String?, !persist\n\n ### The scopes this key provides access to.\n scopeNames: List\n\n ### The method of signing in this key was generated through. This can be email\n ### or different social logins.\n method: String\nindexes:\n serverpod_auth_key_userId_idx:\n fields: userId\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Your are then responsible for creating/removing entries in this table, the old ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," that used to provide this functionality can be found ",(0,a.jsx)(n.a,{href:"https://github.com/serverpod/serverpod/blob/13795a7bd4c0cc5a03101b6f378cb914673046dd/packages/serverpod/lib/src/server/session.dart#L359-L394",children:"here"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-the-session-object",children:"Changes to the Session Object"}),"\n",(0,a.jsx)(n.h3,{id:"removed-deprecated-fields",children:"Removed deprecated fields"}),"\n",(0,a.jsxs)(n.p,{children:["With Serverpod 2.0, we have removed the deprecated legacy database layer from the ",(0,a.jsx)(n.code,{children:"Session"})," object. The ",(0,a.jsx)(n.code,{children:"Session"})," object now incorporates the new database layer, accessed via the ",(0,a.jsx)(n.code,{children:"dbNext"})," field in Serverpod 1.2, under the ",(0,a.jsx)(n.code,{children:"db"})," field."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"session.dbNext.find(...);\n"})}),"\n",(0,a.jsx)(n.p,{children:"becomes"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"session.db.find(...);\n"})}),"\n",(0,a.jsx)(n.h3,{id:"authenticated-user-information-retrieval",children:"Authenticated user information retrieval"}),"\n",(0,a.jsxs)(n.p,{children:["In Serverpod 2.0, we have removed the getters ",(0,a.jsx)(n.code,{children:"scopes"})," and ",(0,a.jsx)(n.code,{children:"authenticatedUser"})," from session. This information is now retrievable through the ",(0,a.jsx)(n.code,{children:"authenticated"})," getter as fields of the returned object."]}),"\n",(0,a.jsx)(n.p,{children:"Replace this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"int? userId = await session.auth.authenticatedUser;\n\nSet? scopes = await session.scopes;\n"})}),"\n",(0,a.jsx)(n.p,{children:"With this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final authenticated = await session.authenticated;\n\n//Read authenticated userId\nint? userId = authenticated?.userId;\n\n//Read scopes\nSet? scopes = authenticated?.scopes;\n"})}),"\n",(0,a.jsxs)(n.p,{children:["If the ",(0,a.jsx)(n.code,{children:"authenticated"})," property is set on the session it effectively means there is an authenticated user making the request."]}),"\n",(0,a.jsx)(n.h3,{id:"authentication-helpers",children:"Authentication helpers"}),"\n",(0,a.jsxs)(n.p,{children:["The field ",(0,a.jsx)(n.code,{children:"auth"})," has been removed and the methods ",(0,a.jsx)(n.code,{children:"signInUser"})," and ",(0,a.jsx)(n.code,{children:"signOutUser"})," have been moved to the ",(0,a.jsx)(n.code,{children:"serverpod_auth"})," module."]}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-database-queries",children:"Changes to database queries"}),"\n",(0,a.jsx)(n.h3,{id:"removed-unsafequerymappedresults",children:"Removed unsafeQueryMappedResults(...)"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," method has been removed. A similar result can now instead be formatted from the ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," result by calling the ",(0,a.jsx)(n.code,{children:"toColumnMap()"})," method for each row of the result. ",(0,a.jsx)(n.code,{children:"toColumnMap"})," returns a map containing the query alias for the column as key and the row-column value as value."]}),"\n",(0,a.jsx)(n.p,{children:"Given a query that performs a join like this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'SELECT\n "company"."id" AS "company.id",\n "company"."name" AS "company.name",\n "company"."townId" AS "company.townId",\n "company_town_town"."id" AS "company_town_town.id",\n "company_town_town"."name" AS "company_town_town.name",\n "company_town_town"."mayorId" AS "company_town_town.mayorId"\nFROM\n "company"\nLEFT JOIN\n "town" AS "company_town_town" ON "company"."townId" = "company_town_town"."id"\nORDER BY\n "company"."name"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The return type from ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," in 1.2 was:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company": {\n "company.id": 40,\n "company.name": "Apple",\n "company.townId": 64\n },\n "town": {\n "company_town_town.id": 64,\n "company_town_town.name": "San Francisco",\n "company_town_town.mayorId": null\n }\n },\n {\n "company": {\n "company.id": 39,\n "company.name": "Serverpod",\n "company.townId": 63\n },\n "town": {\n "company_town_town.id": 63,\n "company_town_town.name": "Stockholm",\n "company_town_town.mayorId": null\n }\n }\n]\n'})}),"\n",(0,a.jsxs)(n.p,{children:["And if ",(0,a.jsx)(n.code,{children:"result.map((row) => row.toColumnMap())"})," is used to format the result from ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," in 2.0, the following result is obtained:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company.id": 38,\n "company.name": "Apple",\n "company.townId": 62,\n "company_town_town.id": 62,\n "company_town_town.name": "San Francisco",\n "company_town_town.mayorId": null\n },\n {\n "company.id": 37,\n "company.name": "Serverpod",\n "company.townId": 61,\n "company_town_town.id": 61,\n "company_town_town.name": "Stockholm",\n "company_town_town.mayorId": null\n }\n]\n'})}),"\n",(0,a.jsx)(n.p,{children:"or for a simple query without aliases:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'SELECT\n "id",\n "name",\n "townId"\nFROM\n "company"\nORDER BY\n "name"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["the return type from ",(0,a.jsx)(n.code,{children:"unsafeQueryMappedResults(...)"})," in 1.2 was:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'[\n {\n "company": {\n "id": 54,\n "name": "Apple",\n "townId": 86\n }\n },\n {\n "company": {\n "id": 53,\n "name": "Serverpod",\n "townId": 85\n }\n }\n]\n'})}),"\n",(0,a.jsxs)(n.p,{children:["and if ",(0,a.jsx)(n.code,{children:"result.map((row) => row.toColumnMap())"})," is used to format the result from ",(0,a.jsx)(n.code,{children:"unsafeQuery(...)"})," in 2.0, the following result is obtained:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:' [\n {\n "id": 54,\n "name": "Apple",\n "townId": 86\n },\n {\n "id": 53,\n "name": "Serverpod",\n "townId": 85\n }\n]\n'})}),"\n",(0,a.jsx)(n.h3,{id:"update-return-type-for-delete-operations",children:"Update return type for delete operations"}),"\n",(0,a.jsxs)(n.p,{children:["The return type for all delete operations has been changed from the ",(0,a.jsx)(n.code,{children:"id"})," of the deleted rows to the actual deleted rows. This makes the return type for the delete operations consistent with the return type of the other database operations. It also dramatically simplifies retrieving and removing rows in concurrent environments."]}),"\n",(0,a.jsx)(n.p,{children:"Return type before the change:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"int companyId = await Company.db.deleteRow(session, company);\nList companyIds = await Company.db.delete(session, [company]);\nList companyIds = await Company.db.deleteWhere(session, where: (t) => t.name.like('%Ltd'));\n"})}),"\n",(0,a.jsx)(n.p,{children:"Return types after the change:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"Company company = await Company.db.deleteRow(session, company);\nList companies = await Company.db.delete(session, [company]);\nList companies = await Company.db.deleteWhere(session, where: (t) => t.name.like('%Ltd'));\n"})}),"\n",(0,a.jsx)(n.h2,{id:"changes-to-database-tables",children:"Changes to database tables"}),"\n",(0,a.jsx)(n.h3,{id:"integer-representation-changed-to-bigint",children:"Integer representation changed to bigint"}),"\n",(0,a.jsxs)(n.p,{children:["Integer representation in the database has changed from ",(0,a.jsx)(n.code,{children:"int"})," to ",(0,a.jsx)(n.code,{children:"bigint"}),". From now on, models with ",(0,a.jsx)(n.code,{children:"int"})," fields will generate database migrations where that field is defined as a ",(0,a.jsx)(n.code,{children:"bigint"})," type in the database."]}),"\n",(0,a.jsxs)(n.p,{children:["This change also applies to the ",(0,a.jsx)(n.code,{children:"id"})," field of models where ",(0,a.jsx)(n.code,{children:"bigserial"})," is now used to generate the id."]}),"\n",(0,a.jsx)(n.p,{children:"The change is compatible with existing databases. Existing migrations therefore, won't be changed by the Serverpod migration system. No manual modification to the database is required if this data representation is not essential for the application. However, all new migrations will be created with the new representation."}),"\n",(0,a.jsx)(n.h4,{id:"why-is-this-change-made",children:"Why is this change made?"}),"\n",(0,a.jsxs)(n.p,{children:["The change was made to ensure that ",(0,a.jsx)(n.a,{href:"https://dart.dev/guides/language/numbers",children:"Dart"})," and the database representation of integers is consistent. Dart uses 64-bit integers, and the ",(0,a.jsx)(n.code,{children:"int"})," type in Dart is a 64-bit integer. The ",(0,a.jsx)(n.code,{children:"int"})," type in PostgreSQL is a 32-bit integer. This means that the ",(0,a.jsx)(n.code,{children:"int"})," type in Dart can represent larger numbers than the ",(0,a.jsx)(n.code,{children:"int"})," type in PostgreSQL. By using ",(0,a.jsx)(n.code,{children:"bigint"})," in PostgreSQL, the integer representation is consistent between Dart and the database."]}),"\n",(0,a.jsxs)(n.p,{children:["In terms of performance, there are usually no significant drawbacks with using ",(0,a.jsx)(n.code,{children:"bigint"})," instead of ",(0,a.jsx)(n.code,{children:"int"}),". In most cases a good index strategy will be more important than the integer representation. Here is a guide that benchmarks the performance of ",(0,a.jsx)(n.code,{children:"int"})," and ",(0,a.jsx)(n.code,{children:"bigint"})," in PostgreSQL: ",(0,a.jsx)(n.a,{href:"https://blog.rustprooflabs.com/2021/06/postgres-bigint-by-default",children:"Use BIGINT in Postgres"})]}),"\n",(0,a.jsx)(n.h4,{id:"ensuring-new-databases-are-created-with-the-new-representation",children:"Ensuring new databases are created with the new representation"}),"\n",(0,a.jsxs)(n.p,{children:["Since existing migrations won't be changed, databases that are created with these will still use ",(0,a.jsx)(n.code,{children:"int"})," to represent integers."]}),"\n",(0,a.jsx)(n.p,{children:"To ensure new databases are created with the new representation, the latest migration should be generated using Serverpod 2.0. It is enough to have an empty migration to ensure new databases use the new representation."}),"\n",(0,a.jsx)(n.p,{children:"A new empty migration can be created by running the following command in the terminal:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"$ serverpod create-migration --force\n"})}),"\n",(0,a.jsx)(n.h4,{id:"migration-of-existing-tables",children:"Migration of existing tables"}),"\n",(0,a.jsx)(n.p,{children:"The migration of existing tables to use the new representation will vary depending on the database content. Utilizing the wrong migration strategy might cause downtime for your application. That is the reason Serverpod does not automatically migrate existing tables."}),"\n",(0,a.jsx)(n.h5,{id:"small-tables",children:"Small tables"}),"\n",(0,a.jsx)(n.p,{children:"A simple way to migrate for small tables is to execute the following sql query to the database:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:'ALTER SEQUENCE "my_table_id_seq" AS bigint;\nALTER TABLE "my_table" ALTER "id" TYPE bigint;\nALTER TABLE "my_table" ALTER "myNumber" TYPE bigint;\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The first two lines modify the id sequence for a table named ",(0,a.jsx)(n.code,{children:'"my_table"'})," to use ",(0,a.jsx)(n.code,{children:"bigint"})," instead of ",(0,a.jsx)(n.code,{children:"int"}),". The last line modifies a column of the same table to use ",(0,a.jsx)(n.code,{children:"bigint"}),". The drawback of this approach is that it locks the table during the migration. Therefore, this strategy is not recommended for large tables."]}),"\n",(0,a.jsx)(n.h5,{id:"large-tables",children:"Large tables"}),"\n",(0,a.jsx)(n.p,{children:"Migrating large tables without application downtime is a more complex operation, and the approach will vary depending on the data structure. Below are some gathered resources on the subject."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"http://zemanta.github.io/2021/08/25/column-migration-from-int-to-bigint-in-postgresql/",children:"Zemata - Column migration from INT to BIGINT"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://am2.co/2019/12/changing-a-column-from-int-to-bigint-without-downtime/",children:"AM^2 - Changing a column from int to bigint, without downtime"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://www.crunchydata.com/blog/the-integer-at-the-end-of-the-universe-integer-overflow-in-postgres",children:"Crunch data - The integer at the End of the Universe"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"changes-in-the-authentication-module",children:"Changes in the authentication module"}),"\n",(0,a.jsx)(n.h3,{id:"unsecure-random-disabled-by-default",children:"Unsecure random disabled by default"}),"\n",(0,a.jsxs)(n.p,{children:["The authentication module's default value for allowing unsecure random number generation is now ",(0,a.jsx)(n.code,{children:"false"}),". An exception will be thrown when trying to hash a password if no secure random number generator is available. To preserve the old behavior and enable unsecure random number generation, set the ",(0,a.jsx)(n.code,{children:"allowUnsecureRandom"})," property in the ",(0,a.jsx)(n.code,{children:"AuthConfig"})," to ",(0,a.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"auth.AuthConfig.set(auth.AuthConfig(\n allowUnsecureRandom: true,\n));\n"})}),"\n",(0,a.jsx)(n.h2,{id:"updates-to-serialization-in-serverpod-20",children:"Updates to Serialization in Serverpod 2.0"}),"\n",(0,a.jsx)(n.h3,{id:"general-changes-to-model-serialization",children:"General Changes to Model Serialization"}),"\n",(0,a.jsxs)(n.p,{children:["Serverpod 2.0 significantly streamlines the model serialization process. In earlier versions, the ",(0,a.jsx)(n.code,{children:"fromJson"})," factory constructors needed a ",(0,a.jsx)(n.code,{children:"serializationManager"})," parameter to handle object deserialization. This parameter has now been removed, enhancing simplicity and usability."]}),"\n",(0,a.jsx)(n.h4,{id:"before-change",children:"Before change"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final Map json = classInstance.toJson();\nfinal SerializationManager serializationManager = Protocol();\nfinal ClassName test = ClassName.fromJson(json, serializationManager);\n"})}),"\n",(0,a.jsx)(n.h4,{id:"after-change",children:"After change"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"final Map json = classInstance.toJson();\nfinal ClassName test = ClassName.fromJson(json);\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enhancements-for-custom-serialization",children:"Enhancements for Custom Serialization"}),"\n",(0,a.jsxs)(n.p,{children:["The removal of the ",(0,a.jsx)(n.code,{children:"serializationManager"})," parameter in Serverpod 2.0 simplifies the serialization process not only for general models but also significantly enhances custom serialization workflows.\nFor custom classes that previously utilized unique serialization logic with the ",(0,a.jsx)(n.code,{children:"serializationManager"}),", adjustments may be necessary."]}),"\n",(0,a.jsx)(n.h4,{id:"previous-implementation",children:"Previous Implementation"}),"\n",(0,a.jsxs)(n.p,{children:["In the previous versions, models required the ",(0,a.jsx)(n.code,{children:"serializationManager"})," to be passed explicitly, as shown in the following code snippet:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"factory ClassName.fromJson(\n Map json,\n SerializationManager serializationManager,\n ) {\n return ClassName(\n json['name'],\n );\n }\n"})}),"\n",(0,a.jsx)(n.h4,{id:"updated-implementation",children:"Updated Implementation"}),"\n",(0,a.jsxs)(n.p,{children:["With the release of Serverpod 2.0, the ",(0,a.jsx)(n.code,{children:"fromJson"})," constructor has been simplified and the ",(0,a.jsx)(n.code,{children:"serializationManager"})," has been removed:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"factory ClassName.fromJson(\n Map json,\n ) {\n return ClassName(\n json['name'],\n );\n }\n"})}),"\n",(0,a.jsxs)(n.h2,{id:"deprecation-notice-for-serializableentity",children:["Deprecation Notice for ",(0,a.jsx)(n.code,{children:"SerializableEntity"})]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"SerializableEntity"})," class is deprecated and will be removed in version 3. Please implement the ",(0,a.jsx)(n.code,{children:"SerializableModel"})," interface instead for creating serializable models."]}),"\n",(0,a.jsx)(n.h3,{id:"migration-guide",children:"Migration Guide"}),"\n",(0,a.jsxs)(n.p,{children:["To migrate your code from ",(0,a.jsx)(n.code,{children:"SerializableEntity"})," to ",(0,a.jsx)(n.code,{children:"SerializableModel"}),", replace ",(0,a.jsx)(n.code,{children:"extends SerializableEntity"})," with ",(0,a.jsx)(n.code,{children:"implements SerializableModel"})," in your model classes."]}),"\n",(0,a.jsx)(n.h4,{id:"example",children:"Example"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Before:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"class CustomClass extends SerializableEntity {\n // Your code here\n}\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"After:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-dart",children:"class CustomClass implements SerializableModel {\n // Your code here\n}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const i={},s=a.createContext(i);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/cce58fe7.dbb843db.js b/docs/assets/js/cce58fe7.dd0a4d50.js similarity index 99% rename from docs/assets/js/cce58fe7.dbb843db.js rename to docs/assets/js/cce58fe7.dd0a4d50.js index b36d90937..11a6c5801 100644 --- a/docs/assets/js/cce58fe7.dbb843db.js +++ b/docs/assets/js/cce58fe7.dd0a4d50.js @@ -1 +1 @@ -"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[6157],{53451:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>o});var s=n(74848),i=n(28453);const r={},d="Working with models",l={id:"concepts/models",title:"Working with models",description:'Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular .yaml files within lib/src/models is supported, but it is recommended to use .spy.yaml (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the Serverpod Extension for VS Code.',source:"@site/versioned_docs/version-1.2.0/05-concepts/02-models.md",sourceDirName:"05-concepts",slug:"/concepts/models",permalink:"/1.2.0/concepts/models",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/versioned_docs/version-1.2.0/05-concepts/02-models.md",tags:[],version:"1.2.0",sidebarPosition:2,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Working with endpoints",permalink:"/1.2.0/concepts/working-with-endpoints"},next:{title:"Custom serialization",permalink:"/1.2.0/concepts/serialization"}},a={},o=[{value:"Class",id:"class",level:2},{value:"Limiting visibility of a generated class",id:"limiting-visibility-of-a-generated-class",level:3},{value:"Exception",id:"exception",level:2},{value:"Enum",id:"enum",level:2},{value:"Adding documentation",id:"adding-documentation",level:2},{value:"Generated code",id:"generated-code",level:2},{value:"copyWith",id:"copywith",level:3},{value:"toJson / fromJson",id:"tojson--fromjson",level:3},{value:"Custom methods",id:"custom-methods",level:3},{value:"Keywords",id:"keywords",level:2}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"working-with-models",children:"Working with models"})}),"\n",(0,s.jsxs)(t.p,{children:["Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular ",(0,s.jsx)(t.code,{children:".yaml"})," files within ",(0,s.jsx)(t.code,{children:"lib/src/models"})," is supported, but it is recommended to use ",(0,s.jsx)(t.code,{children:".spy.yaml"}),' (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the ',(0,s.jsx)(t.a,{href:"https://marketplace.visualstudio.com/items?itemName=serverpod.serverpod",children:"Serverpod Extension"})," for VS Code."]}),"\n",(0,s.jsx)(t.p,{children:"The files are analyzed by the Serverpod CLI when generating the project and creating migrations."}),"\n",(0,s.jsxs)(t.p,{children:["Run ",(0,s.jsx)(t.code,{children:"serverpod generate"})," to generate dart classes from the model files."]}),"\n",(0,s.jsx)(t.h2,{id:"class",children:"Class"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: Company\nfields:\n name: String\n foundedDate: DateTime?\n employees: List\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Supported types are ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/bool-class.html",children:"bool"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/int-class.html",children:"int"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/double-class.html",children:"double"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/String-class.html",children:"String"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Duration-class.html",children:"Duration"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/DateTime-class.html",children:"DateTime"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-typed_data/ByteData-class.html",children:"ByteData"}),", ",(0,s.jsx)(t.a,{href:"https://pub.dev/documentation/uuid/latest/uuid_value/UuidValue-class.html",children:"UuidValue"}),", and other serializable ",(0,s.jsx)(t.a,{href:"#class",children:"classes"}),", ",(0,s.jsx)(t.a,{href:"#exception",children:"exceptions"})," and ",(0,s.jsx)(t.a,{href:"#enum",children:"enums"}),". You can also use ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/List-class.html",children:"List"}),"s and ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Map-class.html",children:"Map"}),"s of the supported types, just make sure to specify the types. Null safety is supported. Once your classes are generated, you can use them as parameters or return types to endpoint methods."]}),"\n",(0,s.jsx)(t.h3,{id:"limiting-visibility-of-a-generated-class",children:"Limiting visibility of a generated class"}),"\n",(0,s.jsx)(t.p,{children:"By default, generated code for your serializable objects is available both on the server and the client. You may want to have the code on the server side only. E.g., if the serializable object is connected to a database table containing private information."}),"\n",(0,s.jsx)(t.p,{children:"To make a serializable class generated only on the server side, set the serverOnly property to true."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: MyPrivateClass\nserverOnly: true\nfields:\n hiddenSecretKey: String\n"})}),"\n",(0,s.jsxs)(t.p,{children:["It is also possible to set a ",(0,s.jsx)(t.code,{children:"scope"})," on a per-field basis. By default all fields are visible to both the server and the client. The available scopes are ",(0,s.jsx)(t.code,{children:"all"}),", ",(0,s.jsx)(t.code,{children:"serverOnly"}),", ",(0,s.jsx)(t.code,{children:"none"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: SelectivelyHiddenClass\nfields:\n hiddenSecretKey: String, scope=serverOnly\n publicKey: String\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["Serverpod's models can easily be saved to or read from the database. You can read more about this in the ",(0,s.jsx)(t.a,{href:"database/models",children:"Database"})," section."]})}),"\n",(0,s.jsx)(t.h2,{id:"exception",children:"Exception"}),"\n",(0,s.jsxs)(t.p,{children:["The Serverpod models supports creating exceptions that can be thrown in endpoints by using the ",(0,s.jsx)(t.code,{children:"exception"})," keyword. For more in-depth description on how to work with exceptions see ",(0,s.jsx)(t.a,{href:"exceptions",children:"Error handling and exceptions"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"exception: MyException\nfields:\n message: String\n errorType: MyEnum\n"})}),"\n",(0,s.jsx)(t.h2,{id:"enum",children:"Enum"}),"\n",(0,s.jsxs)(t.p,{children:["It is easy to add custom enums with serialization support by using the ",(0,s.jsx)(t.code,{children:"enum"})," keyword."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsx)(t.p,{children:"By default the serialization will convert the enum to an int representing the index of the value. Changing the order may therefore have unforeseen consequences when reusing old data (such as from a database). Changing the serialization to be based on the name instead of index is easy."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nserialized: byName\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.code,{children:"serialized"})," has two valid values ",(0,s.jsx)(t.code,{children:"byName"})," and ",(0,s.jsx)(t.code,{children:"byIndex"}),". When using ",(0,s.jsx)(t.code,{children:"byName"})," the string literal of the enum is used, when using ",(0,s.jsx)(t.code,{children:"byIndex"})," the index value (0, 1, 2, etc) is used."]}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["It's recommended to always set ",(0,s.jsx)(t.code,{children:"serialized"})," to ",(0,s.jsx)(t.code,{children:"byName"})," in any new Enum models, as this is less fragile and will be changed to the default setting in version 2 of Serverpod."]})}),"\n",(0,s.jsx)(t.h2,{id:"adding-documentation",children:"Adding documentation"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod allows you to add documentation to your serializable objects in a similar way that you would add documentation to your Dart code. Use three hashes (###) to indicate that a comment should be considered documentation."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"### Information about a company.\nclass: Company\nfields:\n ### The name of the company.\n name: String\n\n ### The date the company was founded, if known.\n foundedDate: DateTime?\n\n ### A list of people currently employed at the company.\n employees: List\n"})}),"\n",(0,s.jsx)(t.h2,{id:"generated-code",children:"Generated code"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod generates some convenience methods on the Dart classes."}),"\n",(0,s.jsx)(t.h3,{id:"copywith",children:"copyWith"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method allows for efficient object copying with selective field updates and is available on all generated ",(0,s.jsx)(t.code,{children:"class"}),"es. Here's how it operates:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"var john = User(name: 'John Doe', age: 25);\nvar jane = john.copyWith(name: 'Jane Doe');\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method generates a deep copy of an object, preserving all original fields unless explicitly modified. It can distinguish between a field set to ",(0,s.jsx)(t.code,{children:"null"})," and a field left unspecified (undefined). When using ",(0,s.jsx)(t.code,{children:"copyWith"}),", any field you don't update remains unchanged in the new object."]}),"\n",(0,s.jsx)(t.h3,{id:"tojson--fromjson",children:"toJson / fromJson"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"toJson"})," and ",(0,s.jsx)(t.code,{children:"fromJson"})," methods are generated on all models to help with serialization. Serverpod manages all serialization for you out of the box and you will rarely have to use these methods by your self. See the ",(0,s.jsx)(t.a,{href:"serialization",children:"Serialization"})," section for more info."]}),"\n",(0,s.jsx)(t.h3,{id:"custom-methods",children:"Custom methods"}),"\n",(0,s.jsxs)(t.p,{children:["Sometimes you will want to add custom methods to the generated classes. The easiest way to do this is with ",(0,s.jsx)(t.a,{href:"https://dart.dev/language/extension-methods",children:"Dart's extension feature"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"extension MyExtension on MyClass {\n bool isCustomMethod() {\n return true;\n }\n}\n"})}),"\n",(0,s.jsx)(t.h2,{id:"keywords",children:"Keywords"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:(0,s.jsx)(t.strong,{children:"Keyword"})}),(0,s.jsx)(t.th,{children:"Note"}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#class",children:"class"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#exception",children:"exception"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#enum",children:"enum"})})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"values"})})}),(0,s.jsx)(t.td,{children:"A special key for enums with a list of all enum values."}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"serialized"})})}),(0,s.jsx)(t.td,{children:"Sets the mode enums are serialized in"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"serverOnly"})})}),(0,s.jsx)(t.td,{children:"Boolean flag if code generator only should create the code for the server."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"table"})})}),(0,s.jsx)(t.td,{children:"A name for the database table, enables generation of database code."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/migrations#opt-out-of-migrations",children:(0,s.jsx)(t.strong,{children:"managedMigration"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to opt out of the database migration system."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"fields"})})}),(0,s.jsx)(t.td,{children:"All fields in the generated class should be listed here."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"type (fields)"})})}),(0,s.jsx)(t.td,{children:"Denotes the data type for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"scope"})})}),(0,s.jsx)(t.td,{children:"Denotes the scope for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"persist"})})}),(0,s.jsxs)(t.td,{children:["A boolean flag if the data should be stored in the database or not can be negated with ",(0,s.jsx)(t.code,{children:"!persist"})]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one",children:(0,s.jsx)(t.strong,{children:"relation"})})}),(0,s.jsx)(t.td,{children:"Sets a relation between model files, requires a table name to be set."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#bidirectional-relations",children:(0,s.jsx)(t.strong,{children:"name"})})}),(0,s.jsx)(t.td,{children:"Give a name to a relation to pair them."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#with-an-id-field",children:(0,s.jsx)(t.strong,{children:"parent"})})}),(0,s.jsx)(t.td,{children:"Sets the parent table on a relation."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#custom-foreign-key-field",children:(0,s.jsx)(t.strong,{children:"field"})})}),(0,s.jsx)(t.td,{children:"A manual specified foreign key field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onUpdate"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when updating data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onDelete"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when deleting data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#optional-relation",children:(0,s.jsx)(t.strong,{children:"optional"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to make a relation optional."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"indexes"})})}),(0,s.jsx)(t.td,{children:"Create indexes on your fields / columns."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"fields (index)"})})}),(0,s.jsx)(t.td,{children:"List the fields to create the indexes on."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"type (index)"})})}),(0,s.jsx)(t.td,{children:"The type of index to create."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"unique"})})}),(0,s.jsx)(t.td,{children:"Boolean flag to make the entries unique in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>d,x:()=>l});var s=n(96540);const i={},r=s.createContext(i);function d(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkserverpod_docs=self.webpackChunkserverpod_docs||[]).push([[6157],{53451:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>o});var s=n(74848),i=n(28453);const r={},d="Working with models",l={id:"concepts/models",title:"Working with models",description:'Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular .yaml files within lib/src/models is supported, but it is recommended to use .spy.yaml (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the Serverpod Extension for VS Code.',source:"@site/versioned_docs/version-1.2.0/05-concepts/02-models.md",sourceDirName:"05-concepts",slug:"/concepts/models",permalink:"/1.2.0/concepts/models",draft:!1,unlisted:!1,editUrl:"https://github.com/serverpod/serverpod_docs/tree/main/versioned_docs/version-1.2.0/05-concepts/02-models.md",tags:[],version:"1.2.0",sidebarPosition:2,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Working with endpoints",permalink:"/1.2.0/concepts/working-with-endpoints"},next:{title:"Custom serialization",permalink:"/1.2.0/concepts/serialization"}},a={},o=[{value:"Class",id:"class",level:2},{value:"Limiting visibility of a generated class",id:"limiting-visibility-of-a-generated-class",level:3},{value:"Exception",id:"exception",level:2},{value:"Enum",id:"enum",level:2},{value:"Adding documentation",id:"adding-documentation",level:2},{value:"Generated code",id:"generated-code",level:2},{value:"copyWith",id:"copywith",level:3},{value:"toJson / fromJson",id:"tojson--fromjson",level:3},{value:"Custom methods",id:"custom-methods",level:3},{value:"Keywords",id:"keywords",level:2}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"working-with-models",children:"Working with models"})}),"\n",(0,s.jsxs)(t.p,{children:["Models are Yaml files used to define serializable classes in Serverpod. They are used to generate Dart code for the server and client, and, if a database table is defined, to generate database code for the server. Using regular ",(0,s.jsx)(t.code,{children:".yaml"})," files within ",(0,s.jsx)(t.code,{children:"lib/src/models"})," is supported, but it is recommended to use ",(0,s.jsx)(t.code,{children:".spy.yaml"}),' (.spy stands for "Server Pod Yaml") to leverage syntax highlighting provided by the ',(0,s.jsx)(t.a,{href:"https://marketplace.visualstudio.com/items?itemName=serverpod.serverpod",children:"Serverpod Extension"})," for VS Code."]}),"\n",(0,s.jsx)(t.p,{children:"The files are analyzed by the Serverpod CLI when generating the project and creating migrations."}),"\n",(0,s.jsxs)(t.p,{children:["Run ",(0,s.jsx)(t.code,{children:"serverpod generate"})," to generate dart classes from the model files."]}),"\n",(0,s.jsx)(t.h2,{id:"class",children:"Class"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: Company\nfields:\n name: String\n foundedDate: DateTime?\n employees: List\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Supported types are ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/bool-class.html",children:"bool"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/int-class.html",children:"int"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/double-class.html",children:"double"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/String-class.html",children:"String"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Duration-class.html",children:"Duration"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/DateTime-class.html",children:"DateTime"}),", ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-typed_data/ByteData-class.html",children:"ByteData"}),", ",(0,s.jsx)(t.a,{href:"https://pub.dev/documentation/uuid/latest/uuid_value/UuidValue-class.html",children:"UuidValue"}),", and other serializable ",(0,s.jsx)(t.a,{href:"#class",children:"classes"}),", ",(0,s.jsx)(t.a,{href:"#exception",children:"exceptions"})," and ",(0,s.jsx)(t.a,{href:"#enum",children:"enums"}),". You can also use ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/List-class.html",children:"List"}),"s and ",(0,s.jsx)(t.a,{href:"https://api.dart.dev/dart-core/Map-class.html",children:"Map"}),"s of the supported types, just make sure to specify the types. Null safety is supported. Once your classes are generated, you can use them as parameters or return types to endpoint methods."]}),"\n",(0,s.jsx)(t.h3,{id:"limiting-visibility-of-a-generated-class",children:"Limiting visibility of a generated class"}),"\n",(0,s.jsx)(t.p,{children:"By default, generated code for your serializable objects is available both on the server and the client. You may want to have the code on the server side only. E.g., if the serializable object is connected to a database table containing private information."}),"\n",(0,s.jsx)(t.p,{children:"To make a serializable class generated only on the server side, set the serverOnly property to true."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: MyPrivateClass\nserverOnly: true\nfields:\n hiddenSecretKey: String\n"})}),"\n",(0,s.jsxs)(t.p,{children:["It is also possible to set a ",(0,s.jsx)(t.code,{children:"scope"})," on a per-field basis. By default all fields are visible to both the server and the client. The available scopes are ",(0,s.jsx)(t.code,{children:"all"}),", ",(0,s.jsx)(t.code,{children:"serverOnly"}),", ",(0,s.jsx)(t.code,{children:"none"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"class: SelectivelyHiddenClass\nfields:\n hiddenSecretKey: String, scope=serverOnly\n publicKey: String\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["Serverpod's models can easily be saved to or read from the database. You can read more about this in the ",(0,s.jsx)(t.a,{href:"database/models",children:"Database"})," section."]})}),"\n",(0,s.jsx)(t.h2,{id:"exception",children:"Exception"}),"\n",(0,s.jsxs)(t.p,{children:["The Serverpod models supports creating exceptions that can be thrown in endpoints by using the ",(0,s.jsx)(t.code,{children:"exception"})," keyword. For more in-depth description on how to work with exceptions see ",(0,s.jsx)(t.a,{href:"exceptions",children:"Error handling and exceptions"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"exception: MyException\nfields:\n message: String\n errorType: MyEnum\n"})}),"\n",(0,s.jsx)(t.h2,{id:"enum",children:"Enum"}),"\n",(0,s.jsxs)(t.p,{children:["It is easy to add custom enums with serialization support by using the ",(0,s.jsx)(t.code,{children:"enum"})," keyword."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsx)(t.p,{children:"By default the serialization will convert the enum to an int representing the index of the value. Changing the order may therefore have unforeseen consequences when reusing old data (such as from a database). Changing the serialization to be based on the name instead of index is easy."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enum: Animal\nserialized: byName\nvalues:\n - dog\n - cat\n - bird\n"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.code,{children:"serialized"})," has two valid values ",(0,s.jsx)(t.code,{children:"byName"})," and ",(0,s.jsx)(t.code,{children:"byIndex"}),". When using ",(0,s.jsx)(t.code,{children:"byName"})," the string literal of the enum is used, when using ",(0,s.jsx)(t.code,{children:"byIndex"})," the index value (0, 1, 2, etc) is used."]}),"\n",(0,s.jsx)(t.admonition,{type:"info",children:(0,s.jsxs)(t.p,{children:["It's recommended to always set ",(0,s.jsx)(t.code,{children:"serialized"})," to ",(0,s.jsx)(t.code,{children:"byName"})," in any new Enum models, as this is less fragile and will be changed to the default setting in version 3 of Serverpod."]})}),"\n",(0,s.jsx)(t.h2,{id:"adding-documentation",children:"Adding documentation"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod allows you to add documentation to your serializable objects in a similar way that you would add documentation to your Dart code. Use three hashes (###) to indicate that a comment should be considered documentation."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"### Information about a company.\nclass: Company\nfields:\n ### The name of the company.\n name: String\n\n ### The date the company was founded, if known.\n foundedDate: DateTime?\n\n ### A list of people currently employed at the company.\n employees: List\n"})}),"\n",(0,s.jsx)(t.h2,{id:"generated-code",children:"Generated code"}),"\n",(0,s.jsx)(t.p,{children:"Serverpod generates some convenience methods on the Dart classes."}),"\n",(0,s.jsx)(t.h3,{id:"copywith",children:"copyWith"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method allows for efficient object copying with selective field updates and is available on all generated ",(0,s.jsx)(t.code,{children:"class"}),"es. Here's how it operates:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"var john = User(name: 'John Doe', age: 25);\nvar jane = john.copyWith(name: 'Jane Doe');\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"copyWith"})," method generates a deep copy of an object, preserving all original fields unless explicitly modified. It can distinguish between a field set to ",(0,s.jsx)(t.code,{children:"null"})," and a field left unspecified (undefined). When using ",(0,s.jsx)(t.code,{children:"copyWith"}),", any field you don't update remains unchanged in the new object."]}),"\n",(0,s.jsx)(t.h3,{id:"tojson--fromjson",children:"toJson / fromJson"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"toJson"})," and ",(0,s.jsx)(t.code,{children:"fromJson"})," methods are generated on all models to help with serialization. Serverpod manages all serialization for you out of the box and you will rarely have to use these methods by your self. See the ",(0,s.jsx)(t.a,{href:"serialization",children:"Serialization"})," section for more info."]}),"\n",(0,s.jsx)(t.h3,{id:"custom-methods",children:"Custom methods"}),"\n",(0,s.jsxs)(t.p,{children:["Sometimes you will want to add custom methods to the generated classes. The easiest way to do this is with ",(0,s.jsx)(t.a,{href:"https://dart.dev/language/extension-methods",children:"Dart's extension feature"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-dart",children:"extension MyExtension on MyClass {\n bool isCustomMethod() {\n return true;\n }\n}\n"})}),"\n",(0,s.jsx)(t.h2,{id:"keywords",children:"Keywords"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:(0,s.jsx)(t.strong,{children:"Keyword"})}),(0,s.jsx)(t.th,{children:"Note"}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#class",children:"class"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#exception",children:"exception"})}),(0,s.jsx)(t.th,{style:{textAlign:"center"},children:(0,s.jsx)(t.a,{href:"#enum",children:"enum"})})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"values"})})}),(0,s.jsx)(t.td,{children:"A special key for enums with a list of all enum values."}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#enum",children:(0,s.jsx)(t.strong,{children:"serialized"})})}),(0,s.jsx)(t.td,{children:"Sets the mode enums are serialized in"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"serverOnly"})})}),(0,s.jsx)(t.td,{children:"Boolean flag if code generator only should create the code for the server."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"table"})})}),(0,s.jsx)(t.td,{children:"A name for the database table, enables generation of database code."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/migrations#opt-out-of-migrations",children:(0,s.jsx)(t.strong,{children:"managedMigration"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to opt out of the database migration system."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"fields"})})}),(0,s.jsx)(t.td,{children:"All fields in the generated class should be listed here."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#class",children:(0,s.jsx)(t.strong,{children:"type (fields)"})})}),(0,s.jsx)(t.td,{children:"Denotes the data type for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"#limiting-visibility-of-a-generated-class",children:(0,s.jsx)(t.strong,{children:"scope"})})}),(0,s.jsx)(t.td,{children:"Denotes the scope for a field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/models",children:(0,s.jsx)(t.strong,{children:"persist"})})}),(0,s.jsxs)(t.td,{children:["A boolean flag if the data should be stored in the database or not can be negated with ",(0,s.jsx)(t.code,{children:"!persist"})]}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one",children:(0,s.jsx)(t.strong,{children:"relation"})})}),(0,s.jsx)(t.td,{children:"Sets a relation between model files, requires a table name to be set."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#bidirectional-relations",children:(0,s.jsx)(t.strong,{children:"name"})})}),(0,s.jsx)(t.td,{children:"Give a name to a relation to pair them."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#with-an-id-field",children:(0,s.jsx)(t.strong,{children:"parent"})})}),(0,s.jsx)(t.td,{children:"Sets the parent table on a relation."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#custom-foreign-key-field",children:(0,s.jsx)(t.strong,{children:"field"})})}),(0,s.jsx)(t.td,{children:"A manual specified foreign key field."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onUpdate"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when updating data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/referential-actions",children:(0,s.jsx)(t.strong,{children:"onDelete"})})}),(0,s.jsx)(t.td,{children:"Set the referential actions when deleting data in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/relations/one-to-one#optional-relation",children:(0,s.jsx)(t.strong,{children:"optional"})})}),(0,s.jsx)(t.td,{children:"A boolean flag to make a relation optional."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"indexes"})})}),(0,s.jsx)(t.td,{children:"Create indexes on your fields / columns."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"fields (index)"})})}),(0,s.jsx)(t.td,{children:"List the fields to create the indexes on."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"type (index)"})})}),(0,s.jsx)(t.td,{children:"The type of index to create."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.a,{href:"database/indexing",children:(0,s.jsx)(t.strong,{children:"unique"})})}),(0,s.jsx)(t.td,{children:"Boolean flag to make the entries unique in the database."}),(0,s.jsx)(t.td,{style:{textAlign:"center"},children:"\u2705"}),(0,s.jsx)(t.td,{style:{textAlign:"center"}}),(0,s.jsx)(t.td,{style:{textAlign:"center"}})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>d,x:()=>l});var s=n(96540);const i={},r=s.createContext(i);function d(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/runtime~main.e1bfa786.js b/docs/assets/js/runtime~main.238171b8.js similarity index 98% rename from docs/assets/js/runtime~main.e1bfa786.js rename to docs/assets/js/runtime~main.238171b8.js index ac465d937..982fd3f78 100644 --- a/docs/assets/js/runtime~main.e1bfa786.js +++ b/docs/assets/js/runtime~main.238171b8.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,c,f,d,b={},r={};function t(e){var a=r[e];if(void 0!==a)return a.exports;var c=r[e]={exports:{}};return b[e].call(c.exports,c,c.exports,t),c.exports}t.m=b,e=[],t.O=(a,c,f,d)=>{if(!c){var b=1/0;for(n=0;n=d)&&Object.keys(t.O).every((e=>t.O[e](c[o])))?c.splice(o--,1):(r=!1,d0&&e[n-1][2]>d;n--)e[n]=e[n-1];e[n]=[c,f,d]},t.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return t.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,t.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var d=Object.create(null);t.r(d);var b={};a=a||[null,c({}),c([]),c(c)];for(var r=2&f&&e;"object"==typeof r&&!~a.indexOf(r);r=c(r))Object.getOwnPropertyNames(r).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,t.d(d,b),d},t.d=(e,a)=>{for(var c in a)t.o(a,c)&&!t.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},t.f={},t.e=e=>Promise.all(Object.keys(t.f).reduce(((a,c)=>(t.f[c](e,a),a)),[])),t.u=e=>"assets/js/"+({456:"cb867d98",565:"3f04b2f3",762:"cdc118a8",1160:"638e38ae",1171:"b685e31b",1572:"02c0cfe0",1705:"1921e4ca",1832:"bdc5a52e",1923:"b32c213b",1970:"dbf9e27d",2278:"27e827f8",2295:"0a5c01b2",2496:"3874f1bf",2730:"ac6e050c",3202:"8e7261c9",3230:"9d217e1f",3249:"05ec9480",3392:"reactPlayerVidyard",3607:"d8d6d57b",3783:"a6c3ea4a",3877:"79840965",3900:"ecb3c634",4272:"17dc776d",4276:"7a3d47b3",4499:"f149b10e",4550:"e3443ce0",4574:"976a2d80",4645:"9644aa4e",5e3:"da698f4c",5344:"8baf194b",5352:"52f87500",5441:"af1c5d2b",5623:"10ad1fa6",5819:"e4a796aa",5827:"3d277f18",5885:"3e4a4cb2",6157:"cce58fe7",6215:"f3467f26",6262:"27b43779",6265:"46b54090",6308:"2890c80c",6463:"reactPlayerKaltura",6486:"2e1ee4ed",6497:"5112ebe3",6615:"7b06977d",6918:"89b55a09",7161:"19e323d1",7267:"2db5c390",7606:"7517a61c",7701:"c2b45dbb",7785:"95bf5f56",8271:"94b2bc9a",8349:"06a408fe",8500:"4c5c4c2e",8734:"82e43b76",8927:"b8787c81",9264:"1caa8cdb",9524:"daec0d60",9606:"4519f039",9640:"5589c54d",9647:"5e95c892",9671:"e64edb60",9837:"5a0a1617",10348:"fca5fdb4",10700:"313c9eb1",10845:"5c1eff22",10907:"f7ae65ac",11139:"dc7352a7",11184:"8af032d3",11301:"f584139f",11567:"22dd74f7",11607:"ef2492df",11784:"45dd886d",11934:"b809d820",11965:"1457ddcd",12007:"90ec8c6b",12042:"reactPlayerTwitch",12237:"b6f81eaa",12716:"d2aa311d",12766:"4934de22",12827:"28967b3e",13018:"076cf272",13019:"d3938b1f",13455:"5839343c",13535:"e84b4e80",13585:"ea237062",13650:"2d11a680",14237:"95a5d2b2",14715:"fc8c8cde",14936:"7c8e5227",15066:"fe3f3783",15246:"83c6f999",15447:"30bd0f5b",16328:"reactPlayerDailyMotion",16602:"616631fd",16678:"710ac1c1",16869:"444a6d4e",16884:"4ed1e0ac",16945:"5596dd05",17021:"828ace52",17209:"f9bde383",17289:"45939ed5",17320:"55f37562",17776:"070c8c93",17820:"ebd05845",18093:"0841186f",18401:"17896441",18446:"reactPlayerYouTube",19049:"2fca5c64",19738:"87ab7385",20033:"986f0f98",20210:"68401255",20423:"22f51758",20515:"704545ab",20681:"e66f2658",20773:"d4fc3158",20826:"4ab30eec",21611:"82444e58",21983:"57012fa6",22422:"d3af5b3c",22451:"f5a589e7",22611:"59df87e8",22750:"141135bb",23321:"676f1bdb",23452:"5af30237",23453:"ed64c12e",23619:"f6affd6e",23870:"956829f8",24078:"ec91ff36",24158:"1d39c85d",24295:"96523456",24832:"02e41de2",25362:"5bc657fa",25427:"3edac44d",25504:"0f2c2e36",25666:"522ca66b",25691:"9a594c98",25692:"7ca2e59a",26173:"reactPlayerVimeo",26376:"431ffdb5",26499:"a4adf53f",26622:"d9107a6a",27168:"7ac69e68",27350:"65e04ea3",27646:"12407b36",27685:"6aee17c2",27740:"38e32826",28235:"965931d7",29248:"4a49065b",29250:"dec2bd4a",29436:"dc8c27bd",29773:"1a84c7fd",30248:"b1218054",30418:"6feb7661",30473:"3141060a",30528:"1323771c",30765:"85d514f3",30799:"1a39ee04",30941:"4aa94ec1",31165:"926056c1",31267:"08d55cf7",31471:"3f80bb14",31474:"564db590",31727:"2e18ba50",32055:"9037180b",32096:"c090764b",32141:"df1414bb",32163:"3d150a24",32178:"16116660",32406:"5cde491b",32461:"a6311318",32492:"4e689a0b",32504:"7de3e81f",32741:"d9e7b984",32759:"7800d508",32944:"272aa200",33048:"25c6d77a",33098:"71ba2dc1",33460:"9107c65f",33577:"a32c313f",33992:"cbf3c4ec",34321:"6f56eca8",34438:"54cab4d4",34662:"cf3c245e",34726:"1b6591f7",34750:"07e708e9",34935:"6da448d1",34975:"ff5ed6ba",35223:"db7d4591",35540:"ce86e3e6",35563:"e7977816",35654:"dc4059b2",35742:"aba21aa0",35748:"1312139a",35884:"9c9052d1",36058:"a2a1c245",36132:"e8f4756d",36353:"reactPlayerPreview",36731:"bd568e77",36886:"8abbb0ee",36920:"ed772d97",37107:"3817c387",37296:"a2757506",37516:"9f1829f0",37710:"abd13aa2",37850:"b28bd8b1",37990:"441fd5fc",38031:"8ee9837e",38419:"bd6f2233",38471:"caf7731d",38527:"5e7d099e",38610:"c868bccf",38691:"036b5431",38717:"897331c0",38792:"4f0519c7",38853:"fc67ad3d",38864:"fac0eceb",39026:"c7156cf2",39056:"5f6b1733",39080:"511f9951",39408:"fe2e2e26",39431:"cdd4a9c6",39482:"327b0a57",39558:"50f2f9f3",39757:"9e0c2c37",39911:"92466816",40271:"6a734661",40374:"b5dcbe95",40563:"39dec3ba",40575:"33c1d41a",41237:"88a48c42",41507:"16b03284",41865:"fe76eed8",42083:"4048090e",42206:"91aed80e",42434:"5b2d7e3c",42800:"3aa0ab0a",42901:"2115313f",43174:"6ba85e75",43246:"2d16d24d",43444:"d2f6d210",43773:"a81cb65f",43848:"44145933",43888:"ad61550a",43903:"8186ecf9",44046:"5d707891",44486:"c0650537",44602:"69fcd2fc",44609:"c5313007",44630:"65b7208a",44816:"36fcb744",44947:"39ec0930",45141:"b1394c86",45268:"ef4456b5",45295:"f29fc884",45474:"79d28454",45655:"4a55fe3a",45724:"8dfd8953",45742:"c377a04b",46119:"d58f1ee2",46364:"fe522f67",46563:"aeef55f7",46688:"ac3101e9",46921:"d0b9ca74",46961:"2bbc2deb",47120:"dcbfe205",47127:"999788b8",47264:"b9ec56c8",47341:"7f0714d1",47527:"93dcedec",47627:"reactPlayerStreamable",47719:"b7ea99f7",48124:"8f509517",48134:"356ce494",48235:"df15bc7d",48276:"b467d32a",48436:"f6adf820",48552:"954e932f",48579:"566f49fb",48665:"0f4a5c74",49316:"510b9307",49406:"b26210db",49455:"c8139b75",49658:"0d76317c",49921:"fc8b5a5d",50041:"ac002d2b",50404:"98f4e1ec",50765:"bf519c8d",50908:"3fbaac07",51143:"fc6f07d2",51205:"db42f242",51349:"4aec9039",51379:"17f04a83",51637:"81e4ed6a",51780:"eecc43ff",52302:"e7ee6027",52365:"280af06a",52529:"e3d58533",52723:"reactPlayerMux",53084:"23975af2",53148:"9b4ab8cd",53357:"1577f7ed",53774:"53998120",54049:"4867e743",54220:"092bf57d",54530:"a271ef09",54582:"984d6493",54905:"98d962c5",55011:"49145cdf",55388:"b2419a00",55664:"169f3d24",56264:"46eeb6cb",56282:"d636c09f",56383:"ecaa7076",56420:"fd4b36bb",56684:"378935ce",56764:"805a59dc",57035:"f527bef3",57356:"bb9c591b",57694:"21b7a589",57790:"1b218eaa",57869:"a7edc2bd",58022:"c134ef8a",58215:"1111b27e",58718:"afb7a97b",58800:"5144cf5e",59075:"6e29a506",59221:"76259cc3",59332:"857097c6",59409:"a64b2578",59599:"1e1f8072",59600:"ac9d9d69",59949:"5c6f6ba9",60365:"bd118f84",60759:"719163ad",60880:"640696ee",60886:"c10a0985",60893:"6fbf0c67",60908:"0eebd274",61114:"3cc71396",61252:"3b66921f",61273:"099a3596",61291:"d38e3f9f",61358:"3d1ae229",61368:"f28f059c",61505:"e58556b2",61977:"7570de64",62059:"0893faed",62134:"0d7acd84",62357:"6d2a4d3f",62362:"44463284",62573:"bd1cffff",62921:"1d7c691c",62929:"f5fed352",63474:"98c94590",63538:"06393fc1",63706:"2b67eda4",63737:"53e9dd7a",63747:"fb72d7b2",63960:"a6397568",64558:"b91fbf2a",64641:"eac16e1d",64651:"4c781063",64665:"6f44ab90",65110:"063d75bd",65142:"eb4c176e",65433:"616bfcf6",65542:"af754a1f",65655:"1ebbfca8",65755:"bafd283f",65784:"90239e6e",65866:"419cd6b8",66225:"9f8e6d57",66339:"03b2528f",66811:"3e87058f",66850:"0c695afe",66868:"3c4af576",66885:"5e253f2f",66929:"da54b976",67068:"ae0eacdd",67098:"a7bd4aaa",67217:"726a6c22",67349:"61ff6850",67458:"0d271e1e",67532:"49fed513",67570:"reactPlayerMixcloud",67714:"9d7352c0",68230:"3cf6fa35",68364:"812775a4",68391:"24557dbc",68700:"96331245",68874:"10ea0b82",68912:"2c2832e4",68915:"62de5d73",68960:"358c2507",68962:"af68ae04",69050:"4ac2e930",69779:"3c9432f0",69816:"20d56cb7",69891:"62037464",69979:"reactPlayerSoundCloud",70326:"c3373259",70934:"d44e0d1c",71247:"308471de",71383:"087cd58c",71826:"a4c89d62",71907:"86a8bb6c",71967:"4fa4eafa",72074:"71319bec",72132:"83ac10ed",72231:"fe170cc9",72561:"adce8179",73107:"646cbece",73379:"9d779d8b",73932:"2020ed93",73939:"2ed96714",74081:"ce4dbf6d",74583:"4bfca71d",74780:"ebde045d",74834:"d26a73b8",74860:"00d14154",75412:"5390e21f",75702:"307525ba",75822:"2db99065",75868:"071f33a8",75965:"b48f41b9",76093:"7d63aba8",76224:"03b3cfd2",76238:"8615e055",76372:"d802bb56",76768:"8bed5a26",76973:"78ae7ec8",77137:"42abcd4d",77313:"ee65edec",77318:"67e77328",77757:"f6f476f1",78007:"8eead450",78416:"068743c8",78631:"b7b014bf",78702:"82ea7079",79048:"a94703ab",79052:"6d717251",79225:"526e379a",79354:"4118187a",79825:"2d4af3bf",79956:"9e09f891",79983:"a7f483d1",80549:"afde3230",80721:"05fa9a60",81509:"4ead9a95",81657:"f8189ec4",81790:"42a9b3c5",81849:"2e3fc0f9",82075:"056b386b",82201:"18910d94",82261:"0c6fe626",82439:"e4eafb12",82477:"2ca08277",83287:"7af31c45",83752:"efe5610c",83943:"9c5d9512",84219:"51e50f95",84331:"79e0e7f1",84605:"8552f549",84656:"813cfb2f",84750:"aefdd881",84850:"bc03f89b",85462:"9270ba4f",85527:"5143312c",85528:"21e10cde",85556:"21a4ba71",85943:"05fbef88",86012:"da202fdd",86037:"eaeab60b",86057:"9fbfaf6d",86106:"1877d9d5",86298:"e2d6ba1f",86886:"7b33c27b",86887:"reactPlayerFacebook",86992:"3fe65583",87012:"869ae8a7",87126:"b916a1ab",87402:"c3094240",87510:"9d36f238",87760:"0773e78b",88048:"73ca4188",88131:"c2237e68",88494:"504d78e0",88495:"801276a1",88790:"51c7df8c",88843:"45926b62",88946:"95ec96e5",89598:"4b6eee9a",90049:"cc180519",90381:"869d42f3",90642:"07006f9e",90780:"098f2604",91131:"468d57a9",91258:"227d1fc4",91395:"a0aa5253",92113:"32b8fafb",92170:"4951b372",92687:"cd64d641",92811:"8093477b",92896:"bc69c5bc",93036:"c342bcae",93087:"b0f19176",93842:"26398b18",94594:"c7507218",94642:"da19ecb4",94725:"dd31e7e9",94811:"da071cb8",95191:"c75d145e",95409:"94f11012",96449:"19a6be06",96815:"8d02075b",96991:"4eee9c87",97191:"31b73615",97458:"reactPlayerFilePlayer",97499:"50a12feb",97785:"ac5db01d",98042:"819b642a",98116:"49849746",98175:"5a96e453",98498:"ae22b856",98548:"44a83f6a",98601:"13798859",98996:"65c67349",99094:"08aab21d",99180:"32ebcda7",99340:"reactPlayerWistia",99341:"a1154d73",99591:"e0bec135",99989:"51ddac88"}[e]||e)+"."+{456:"5c30ecdd",565:"94a09b6c",762:"df50c981",1160:"918efc1f",1171:"de34cd0e",1572:"ffbe0cfc",1705:"038460b6",1832:"9614689c",1923:"cb2bc5be",1970:"cac2a9b8",2278:"d475be2b",2295:"e81bbf25",2496:"b540b729",2730:"923b54e1",3202:"f35694a9",3230:"4129121e",3249:"82c7846c",3392:"8464e17b",3607:"2981ded1",3783:"71a2f8e8",3877:"58749100",3900:"0ba32b97",4272:"0900e2a1",4276:"8faf83a5",4499:"ca8d1432",4550:"46f5f770",4574:"1c78d390",4645:"e160e737",5e3:"e340e97d",5344:"1d1077a2",5352:"5ee75c06",5441:"151c62bf",5623:"9548c1a1",5819:"a4a89c82",5827:"5cc9996e",5885:"fcb3bbcb",6157:"dbb843db",6215:"51944600",6262:"794fd95d",6265:"83c21074",6308:"350484bc",6463:"bec1a06c",6486:"4b0eb0a1",6497:"42707b0b",6615:"7db76aa6",6918:"031ec4ab",7161:"2c411627",7267:"ce74b45c",7606:"45b626ad",7701:"316b1161",7785:"f569d217",8271:"bce6ddee",8349:"03f95123",8500:"a390a5ca",8734:"2de05990",8927:"f986535a",9264:"6ae52032",9524:"e7c42f6f",9606:"bff55b72",9640:"b703cc22",9647:"cac24016",9671:"0a30cd6c",9837:"ede23a01",10348:"ec8b3811",10700:"708d8037",10845:"2bc04da3",10907:"eb9d65c3",11139:"303df097",11184:"9d69cbad",11301:"8387b5bf",11567:"432c7b35",11607:"b64b2d67",11784:"9d3408ab",11934:"da61538a",11965:"d6e5dd4d",12007:"fb425a62",12042:"a0c42814",12237:"8a850fa6",12716:"faed95e1",12766:"97abbc05",12827:"144f3020",13018:"c5ad98c6",13019:"c5e3aef7",13455:"1451755d",13535:"88a06537",13585:"a746e017",13650:"62810914",14237:"8c2a2bc3",14715:"95abf808",14936:"6ee147d1",15066:"38ece79e",15246:"fd5943dc",15447:"82977fde",16328:"4fa8d3c8",16602:"f2bf07f8",16678:"cb38a105",16869:"995c6ef6",16884:"bf9abfa1",16945:"1eaf58e9",17021:"6c74822a",17209:"e94a64b5",17289:"e2e7eec1",17320:"9ddeadd7",17776:"f89fd2b8",17820:"623e6e0e",18093:"d4afddde",18401:"30c4f83a",18446:"150ff8a0",19049:"08036f4e",19738:"a816c680",20033:"fa674d6a",20210:"4ea135dd",20423:"076d2946",20515:"85d707fe",20681:"7e97a650",20773:"a2cebc00",20826:"8b874cbc",21611:"6e533a7e",21983:"f9a941e2",22422:"feb00a9e",22451:"ef972e5e",22611:"18587ae4",22750:"a52908e5",23321:"84054f56",23452:"ebba4448",23453:"2ff5cbe7",23619:"c27273de",23870:"3742bfab",24078:"730ca41c",24158:"ce6a000b",24295:"4aae9b71",24832:"af6b73df",25362:"f0170814",25427:"3244da9c",25504:"28938478",25666:"2f0c77bf",25691:"426557b6",25692:"585ab289",26173:"076fef9c",26376:"a1f11cb7",26499:"dd7640ab",26622:"f0629b1b",27168:"07813519",27350:"5fd6e6d7",27646:"0678c8f9",27685:"f20ffda9",27740:"8f7d4d98",28235:"f6cbcccb",29248:"d7c12529",29250:"925abd2b",29436:"7ca95c22",29773:"b8c6f670",30248:"0ad8a16e",30418:"5fc7b2a0",30473:"0abc4692",30528:"435813db",30765:"d86090af",30799:"388c9414",30941:"49876b37",31165:"02614496",31267:"933156b4",31471:"450344fc",31474:"dbbf8152",31727:"d3f3b0b1",32055:"a95bfc3b",32096:"04828676",32141:"bcdc361b",32163:"70936a3c",32178:"36e60316",32406:"bd1dc0ac",32461:"6b4a958d",32492:"30cd7c7f",32504:"754ac7de",32741:"552767cd",32759:"d8e2798a",32944:"6f349f74",33048:"1a010730",33098:"480f07f7",33460:"8f3f92e4",33577:"ce38b0c8",33992:"a7260a35",34321:"ab8e5c20",34438:"8f46a7dd",34662:"8da76618",34726:"90739fe9",34750:"13529313",34935:"59f5597e",34975:"41c5c4bb",35223:"2367e813",35540:"daa770e8",35563:"22b8fd33",35654:"72cb9c74",35742:"e08a145a",35748:"816249d7",35884:"a0bf4e6b",36058:"b63b94d9",36132:"75cbf3f9",36353:"4de9bab6",36731:"1ab1d6ee",36886:"9c9e515a",36920:"3a69befa",37107:"f19c047b",37296:"20763684",37516:"2ab4897d",37710:"5cf4ff57",37850:"ed2f760b",37990:"c6c289b1",38031:"396006c8",38419:"a12c2499",38471:"93b2d4dd",38527:"73056614",38610:"37df5efb",38691:"137dc0f8",38717:"6dbb7b59",38792:"7deb9f3e",38853:"5c9e45fe",38864:"4813ef31",39026:"f2f8a69b",39056:"60f70f39",39080:"b0c77b48",39408:"88db313c",39431:"2bcf2e6d",39482:"7e3b08ef",39503:"18fac5cf",39558:"41945f10",39757:"47703e3b",39911:"646e7dec",40271:"f790e023",40374:"179979e4",40563:"94247613",40575:"4d0b112e",41237:"3bbdf534",41507:"77c30778",41865:"c835f8b0",42083:"2aff9481",42206:"18d5693f",42434:"1f6d6607",42800:"bf6545c0",42901:"2fdbe13a",43174:"013544f4",43246:"ddc98077",43444:"cff02423",43773:"3cc7db7d",43848:"57247e24",43888:"d74ff318",43903:"41a52d13",44046:"a946825c",44486:"28ccbcec",44602:"aaf93cb1",44609:"32c1fd2c",44630:"f2d8976e",44816:"0e7f93b4",44947:"a24467f3",45141:"e3968051",45268:"7006193f",45295:"b0715bed",45474:"1abec566",45655:"c2164e90",45724:"b59ddc1b",45742:"2497dd34",46119:"7805de88",46364:"fdfddfc0",46563:"2e6253c5",46688:"a1d131c8",46921:"260d54e0",46961:"94b493aa",47120:"723a0b3e",47127:"de5390c4",47264:"44b44216",47341:"18ca620e",47527:"d950e87e",47627:"bb35fa43",47719:"646275e7",48124:"55af4038",48134:"b6137268",48235:"bc75728e",48276:"231a1e55",48436:"89305d4a",48552:"c704b5f4",48579:"bbd9e592",48665:"b81074e2",49316:"5e345ac8",49406:"a3ecaee8",49455:"15c58fe1",49658:"3da918b0",49921:"f2c2a1f0",50041:"f7cb55c7",50404:"eb1ab0f9",50765:"479f1916",50908:"a5b524ad",51143:"136727d9",51205:"ee2e77cb",51349:"1e076875",51379:"27ea6246",51637:"ffb79940",51780:"ce9149be",52302:"340b0e6b",52365:"d23ef6a9",52529:"e7cefacb",52723:"3e4df075",53084:"315da40f",53148:"4212deb6",53357:"b5a1c415",53774:"72126425",54049:"4089600b",54220:"d4f185d8",54530:"0bd12311",54582:"4e5700b0",54905:"feb41c26",55011:"95879cb0",55388:"33179a2f",55664:"258a4e6b",56264:"6318e439",56282:"b46c91af",56383:"1ff19ca5",56420:"1972625f",56684:"ab8eab18",56764:"ac5b41d7",57035:"ad79c7ab",57356:"42441995",57694:"a34951a6",57790:"7f79a47a",57869:"89931416",58022:"7b3238f1",58215:"5be13c8d",58718:"a820c36e",58800:"e98ceb1d",59075:"25749229",59221:"658e6207",59332:"84712487",59409:"be73a79d",59599:"780630f8",59600:"ca1b31c5",59949:"0c457c29",60365:"1fd2fa70",60759:"d322d307",60880:"f6ba7287",60886:"67c47b8d",60893:"fe1ea3f9",60908:"e76a5e92",61114:"46cf560e",61252:"0ab3ec6f",61273:"05750299",61291:"0f509abf",61358:"9defced7",61368:"88200516",61505:"1a21d780",61977:"3a915ac8",62059:"27a610be",62134:"136bb77a",62357:"dd821bdf",62362:"8db1be48",62573:"09b3ebf3",62921:"9d42f085",62929:"c76283aa",63474:"bb220697",63538:"7b7f0e14",63706:"6f94bc8f",63737:"af78b6a2",63747:"7c5b8fbd",63960:"9f0fe283",64558:"25e0c733",64641:"4002d9f9",64651:"7df9a0dc",64665:"b140ef8f",65110:"0c2123d1",65142:"d226848c",65433:"d959ad9b",65542:"a7c67c53",65655:"3f647a48",65755:"c46f5968",65784:"b94d85b3",65866:"f9e10c84",66225:"f10f224f",66339:"800c2e61",66811:"945f99d9",66850:"7753ee7f",66868:"65080ded",66885:"1bd3e9c3",66929:"d218d95f",67068:"046fc798",67098:"03929b29",67217:"c9c29188",67349:"b94a3a6a",67458:"f760b356",67532:"60df9b16",67570:"12aff88e",67714:"973cd9fc",68230:"835eaee7",68364:"53e94f68",68391:"262895ce",68700:"64fe7812",68874:"d1febe02",68912:"0c81f713",68915:"57e00474",68960:"18b5e3ad",68962:"d845c0a4",69050:"358b5513",69779:"faba2980",69816:"58af7b00",69891:"80af80ae",69979:"f8f19bc3",70326:"fafebdcb",70934:"73854ef9",71247:"5a63971c",71383:"75b257bc",71826:"9f1c6fe5",71907:"0751c0f3",71967:"1af4694c",72074:"522fdb31",72132:"6e4054d2",72231:"e3c174bf",72561:"1f9fbc90",73107:"ecc6be9c",73379:"16b17994",73932:"b35fd796",73939:"aba6bb06",74081:"b57cba4e",74583:"ce4c9b2f",74780:"b7d71cb3",74834:"15357603",74860:"426c5862",75412:"d72a934a",75702:"3926a131",75822:"1d9852b1",75868:"3118d0c9",75965:"19020673",76093:"8e28eeb6",76224:"8f29238e",76238:"46cbd86e",76372:"297afbc9",76768:"c3ca6e24",76973:"a72e321d",77137:"daff0432",77313:"b92d7b2e",77318:"44e1adab",77757:"eb1c1544",78007:"2b6a8f00",78416:"2ad246f2",78631:"b6f33b62",78702:"ed155bd3",79048:"0f54d2a9",79052:"634be361",79225:"bad5b331",79354:"d6957fa9",79825:"8c4cf900",79956:"4d5ec1eb",79983:"52b6f63f",80549:"a1b3777a",80721:"cdf43ae5",81509:"5a98113a",81657:"d230bb30",81790:"c56f6a89",81849:"0f44253c",82075:"7a5a588a",82201:"c855be90",82237:"787c04ec",82261:"2fc96e72",82439:"18a56b6c",82477:"12d174de",83287:"084dde1a",83752:"d91cc53e",83943:"a64bf43a",84219:"d24c437b",84331:"b37577e8",84605:"8cf0495c",84656:"73c53ede",84750:"1857e769",84850:"f287e029",85462:"ddca2c18",85527:"3afd894d",85528:"74b87448",85556:"fee97575",85943:"e5b4cdd6",86012:"ab7bdaa5",86037:"04050011",86057:"db95e34c",86106:"1290858d",86298:"92e42ef4",86886:"dad3b87b",86887:"508da014",86992:"82004d70",87012:"fd4f4b30",87126:"89adbb17",87402:"abdfd46c",87510:"720f0f93",87760:"72f8f4bb",88048:"2a1833d8",88131:"e11652fa",88494:"7d33658e",88495:"efabda4c",88790:"c5a360b0",88843:"ba8ab281",88946:"350ed3aa",89598:"30bcd67d",90049:"70470979",90381:"4acaccf6",90642:"83acf9a9",90780:"75e3e359",91131:"759062e1",91258:"0a10d55b",91395:"31f57203",92113:"d51c7aa0",92170:"f7b1e9bd",92687:"bed1a1d3",92811:"8a204457",92896:"b265749e",93036:"7c8d08ac",93087:"0090bbd7",93842:"d418eca4",94594:"42c52295",94642:"c0efeaa4",94725:"7118b112",94811:"933445a7",95191:"0ee87f70",95409:"6f87b63a",96449:"9cfed380",96815:"362b1a69",96991:"eca5cf70",97191:"ca75b3a5",97458:"036de6e1",97499:"1a4e721e",97785:"433c50c6",98042:"14a96714",98116:"a22cb511",98175:"b8bdaaeb",98498:"1128c3c9",98548:"0250dbf6",98601:"75b6fdce",98996:"433b1eca",99094:"54319916",99180:"e5d0a4e7",99340:"c5c0cf6c",99341:"4403c816",99591:"4e74c25b",99989:"1ffc7914"}[e]+".js",t.miniCssF=e=>{},t.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),t.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),f={},d="serverpod-docs:",t.l=(e,a,c,b)=>{if(f[e])f[e].push(a);else{var r,o;if(void 0!==c)for(var l=document.getElementsByTagName("script"),n=0;n{r.onerror=r.onload=null,clearTimeout(s);var d=f[e];if(delete f[e],r.parentNode&&r.parentNode.removeChild(r),d&&d.forEach((e=>e(c))),a)return a(c)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:r}),12e4);r.onerror=u.bind(null,r.onerror),r.onload=u.bind(null,r.onload),o&&document.head.appendChild(r)}},t.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.p="/",t.gca=function(e){return e={13798859:"98601",16116660:"32178",17896441:"18401",44145933:"43848",44463284:"62362",49849746:"98116",53998120:"53774",62037464:"69891",68401255:"20210",79840965:"3877",92466816:"39911",96331245:"68700",96523456:"24295",cb867d98:"456","3f04b2f3":"565",cdc118a8:"762","638e38ae":"1160",b685e31b:"1171","02c0cfe0":"1572","1921e4ca":"1705",bdc5a52e:"1832",b32c213b:"1923",dbf9e27d:"1970","27e827f8":"2278","0a5c01b2":"2295","3874f1bf":"2496",ac6e050c:"2730","8e7261c9":"3202","9d217e1f":"3230","05ec9480":"3249",reactPlayerVidyard:"3392",d8d6d57b:"3607",a6c3ea4a:"3783",ecb3c634:"3900","17dc776d":"4272","7a3d47b3":"4276",f149b10e:"4499",e3443ce0:"4550","976a2d80":"4574","9644aa4e":"4645",da698f4c:"5000","8baf194b":"5344","52f87500":"5352",af1c5d2b:"5441","10ad1fa6":"5623",e4a796aa:"5819","3d277f18":"5827","3e4a4cb2":"5885",cce58fe7:"6157",f3467f26:"6215","27b43779":"6262","46b54090":"6265","2890c80c":"6308",reactPlayerKaltura:"6463","2e1ee4ed":"6486","5112ebe3":"6497","7b06977d":"6615","89b55a09":"6918","19e323d1":"7161","2db5c390":"7267","7517a61c":"7606",c2b45dbb:"7701","95bf5f56":"7785","94b2bc9a":"8271","06a408fe":"8349","4c5c4c2e":"8500","82e43b76":"8734",b8787c81:"8927","1caa8cdb":"9264",daec0d60:"9524","4519f039":"9606","5589c54d":"9640","5e95c892":"9647",e64edb60:"9671","5a0a1617":"9837",fca5fdb4:"10348","313c9eb1":"10700","5c1eff22":"10845",f7ae65ac:"10907",dc7352a7:"11139","8af032d3":"11184",f584139f:"11301","22dd74f7":"11567",ef2492df:"11607","45dd886d":"11784",b809d820:"11934","1457ddcd":"11965","90ec8c6b":"12007",reactPlayerTwitch:"12042",b6f81eaa:"12237",d2aa311d:"12716","4934de22":"12766","28967b3e":"12827","076cf272":"13018",d3938b1f:"13019","5839343c":"13455",e84b4e80:"13535",ea237062:"13585","2d11a680":"13650","95a5d2b2":"14237",fc8c8cde:"14715","7c8e5227":"14936",fe3f3783:"15066","83c6f999":"15246","30bd0f5b":"15447",reactPlayerDailyMotion:"16328","616631fd":"16602","710ac1c1":"16678","444a6d4e":"16869","4ed1e0ac":"16884","5596dd05":"16945","828ace52":"17021",f9bde383:"17209","45939ed5":"17289","55f37562":"17320","070c8c93":"17776",ebd05845:"17820","0841186f":"18093",reactPlayerYouTube:"18446","2fca5c64":"19049","87ab7385":"19738","986f0f98":"20033","22f51758":"20423","704545ab":"20515",e66f2658:"20681",d4fc3158:"20773","4ab30eec":"20826","82444e58":"21611","57012fa6":"21983",d3af5b3c:"22422",f5a589e7:"22451","59df87e8":"22611","141135bb":"22750","676f1bdb":"23321","5af30237":"23452",ed64c12e:"23453",f6affd6e:"23619","956829f8":"23870",ec91ff36:"24078","1d39c85d":"24158","02e41de2":"24832","5bc657fa":"25362","3edac44d":"25427","0f2c2e36":"25504","522ca66b":"25666","9a594c98":"25691","7ca2e59a":"25692",reactPlayerVimeo:"26173","431ffdb5":"26376",a4adf53f:"26499",d9107a6a:"26622","7ac69e68":"27168","65e04ea3":"27350","12407b36":"27646","6aee17c2":"27685","38e32826":"27740","965931d7":"28235","4a49065b":"29248",dec2bd4a:"29250",dc8c27bd:"29436","1a84c7fd":"29773",b1218054:"30248","6feb7661":"30418","3141060a":"30473","1323771c":"30528","85d514f3":"30765","1a39ee04":"30799","4aa94ec1":"30941","926056c1":"31165","08d55cf7":"31267","3f80bb14":"31471","564db590":"31474","2e18ba50":"31727","9037180b":"32055",c090764b:"32096",df1414bb:"32141","3d150a24":"32163","5cde491b":"32406",a6311318:"32461","4e689a0b":"32492","7de3e81f":"32504",d9e7b984:"32741","7800d508":"32759","272aa200":"32944","25c6d77a":"33048","71ba2dc1":"33098","9107c65f":"33460",a32c313f:"33577",cbf3c4ec:"33992","6f56eca8":"34321","54cab4d4":"34438",cf3c245e:"34662","1b6591f7":"34726","07e708e9":"34750","6da448d1":"34935",ff5ed6ba:"34975",db7d4591:"35223",ce86e3e6:"35540",e7977816:"35563",dc4059b2:"35654",aba21aa0:"35742","1312139a":"35748","9c9052d1":"35884",a2a1c245:"36058",e8f4756d:"36132",reactPlayerPreview:"36353",bd568e77:"36731","8abbb0ee":"36886",ed772d97:"36920","3817c387":"37107",a2757506:"37296","9f1829f0":"37516",abd13aa2:"37710",b28bd8b1:"37850","441fd5fc":"37990","8ee9837e":"38031",bd6f2233:"38419",caf7731d:"38471","5e7d099e":"38527",c868bccf:"38610","036b5431":"38691","897331c0":"38717","4f0519c7":"38792",fc67ad3d:"38853",fac0eceb:"38864",c7156cf2:"39026","5f6b1733":"39056","511f9951":"39080",fe2e2e26:"39408",cdd4a9c6:"39431","327b0a57":"39482","50f2f9f3":"39558","9e0c2c37":"39757","6a734661":"40271",b5dcbe95:"40374","39dec3ba":"40563","33c1d41a":"40575","88a48c42":"41237","16b03284":"41507",fe76eed8:"41865","4048090e":"42083","91aed80e":"42206","5b2d7e3c":"42434","3aa0ab0a":"42800","2115313f":"42901","6ba85e75":"43174","2d16d24d":"43246",d2f6d210:"43444",a81cb65f:"43773",ad61550a:"43888","8186ecf9":"43903","5d707891":"44046",c0650537:"44486","69fcd2fc":"44602",c5313007:"44609","65b7208a":"44630","36fcb744":"44816","39ec0930":"44947",b1394c86:"45141",ef4456b5:"45268",f29fc884:"45295","79d28454":"45474","4a55fe3a":"45655","8dfd8953":"45724",c377a04b:"45742",d58f1ee2:"46119",fe522f67:"46364",aeef55f7:"46563",ac3101e9:"46688",d0b9ca74:"46921","2bbc2deb":"46961",dcbfe205:"47120","999788b8":"47127",b9ec56c8:"47264","7f0714d1":"47341","93dcedec":"47527",reactPlayerStreamable:"47627",b7ea99f7:"47719","8f509517":"48124","356ce494":"48134",df15bc7d:"48235",b467d32a:"48276",f6adf820:"48436","954e932f":"48552","566f49fb":"48579","0f4a5c74":"48665","510b9307":"49316",b26210db:"49406",c8139b75:"49455","0d76317c":"49658",fc8b5a5d:"49921",ac002d2b:"50041","98f4e1ec":"50404",bf519c8d:"50765","3fbaac07":"50908",fc6f07d2:"51143",db42f242:"51205","4aec9039":"51349","17f04a83":"51379","81e4ed6a":"51637",eecc43ff:"51780",e7ee6027:"52302","280af06a":"52365",e3d58533:"52529",reactPlayerMux:"52723","23975af2":"53084","9b4ab8cd":"53148","1577f7ed":"53357","4867e743":"54049","092bf57d":"54220",a271ef09:"54530","984d6493":"54582","98d962c5":"54905","49145cdf":"55011",b2419a00:"55388","169f3d24":"55664","46eeb6cb":"56264",d636c09f:"56282",ecaa7076:"56383",fd4b36bb:"56420","378935ce":"56684","805a59dc":"56764",f527bef3:"57035",bb9c591b:"57356","21b7a589":"57694","1b218eaa":"57790",a7edc2bd:"57869",c134ef8a:"58022","1111b27e":"58215",afb7a97b:"58718","5144cf5e":"58800","6e29a506":"59075","76259cc3":"59221","857097c6":"59332",a64b2578:"59409","1e1f8072":"59599",ac9d9d69:"59600","5c6f6ba9":"59949",bd118f84:"60365","719163ad":"60759","640696ee":"60880",c10a0985:"60886","6fbf0c67":"60893","0eebd274":"60908","3cc71396":"61114","3b66921f":"61252","099a3596":"61273",d38e3f9f:"61291","3d1ae229":"61358",f28f059c:"61368",e58556b2:"61505","7570de64":"61977","0893faed":"62059","0d7acd84":"62134","6d2a4d3f":"62357",bd1cffff:"62573","1d7c691c":"62921",f5fed352:"62929","98c94590":"63474","06393fc1":"63538","2b67eda4":"63706","53e9dd7a":"63737",fb72d7b2:"63747",a6397568:"63960",b91fbf2a:"64558",eac16e1d:"64641","4c781063":"64651","6f44ab90":"64665","063d75bd":"65110",eb4c176e:"65142","616bfcf6":"65433",af754a1f:"65542","1ebbfca8":"65655",bafd283f:"65755","90239e6e":"65784","419cd6b8":"65866","9f8e6d57":"66225","03b2528f":"66339","3e87058f":"66811","0c695afe":"66850","3c4af576":"66868","5e253f2f":"66885",da54b976:"66929",ae0eacdd:"67068",a7bd4aaa:"67098","726a6c22":"67217","61ff6850":"67349","0d271e1e":"67458","49fed513":"67532",reactPlayerMixcloud:"67570","9d7352c0":"67714","3cf6fa35":"68230","812775a4":"68364","24557dbc":"68391","10ea0b82":"68874","2c2832e4":"68912","62de5d73":"68915","358c2507":"68960",af68ae04:"68962","4ac2e930":"69050","3c9432f0":"69779","20d56cb7":"69816",reactPlayerSoundCloud:"69979",c3373259:"70326",d44e0d1c:"70934","308471de":"71247","087cd58c":"71383",a4c89d62:"71826","86a8bb6c":"71907","4fa4eafa":"71967","71319bec":"72074","83ac10ed":"72132",fe170cc9:"72231",adce8179:"72561","646cbece":"73107","9d779d8b":"73379","2020ed93":"73932","2ed96714":"73939",ce4dbf6d:"74081","4bfca71d":"74583",ebde045d:"74780",d26a73b8:"74834","00d14154":"74860","5390e21f":"75412","307525ba":"75702","2db99065":"75822","071f33a8":"75868",b48f41b9:"75965","7d63aba8":"76093","03b3cfd2":"76224","8615e055":"76238",d802bb56:"76372","8bed5a26":"76768","78ae7ec8":"76973","42abcd4d":"77137",ee65edec:"77313","67e77328":"77318",f6f476f1:"77757","8eead450":"78007","068743c8":"78416",b7b014bf:"78631","82ea7079":"78702",a94703ab:"79048","6d717251":"79052","526e379a":"79225","4118187a":"79354","2d4af3bf":"79825","9e09f891":"79956",a7f483d1:"79983",afde3230:"80549","05fa9a60":"80721","4ead9a95":"81509",f8189ec4:"81657","42a9b3c5":"81790","2e3fc0f9":"81849","056b386b":"82075","18910d94":"82201","0c6fe626":"82261",e4eafb12:"82439","2ca08277":"82477","7af31c45":"83287",efe5610c:"83752","9c5d9512":"83943","51e50f95":"84219","79e0e7f1":"84331","8552f549":"84605","813cfb2f":"84656",aefdd881:"84750",bc03f89b:"84850","9270ba4f":"85462","5143312c":"85527","21e10cde":"85528","21a4ba71":"85556","05fbef88":"85943",da202fdd:"86012",eaeab60b:"86037","9fbfaf6d":"86057","1877d9d5":"86106",e2d6ba1f:"86298","7b33c27b":"86886",reactPlayerFacebook:"86887","3fe65583":"86992","869ae8a7":"87012",b916a1ab:"87126",c3094240:"87402","9d36f238":"87510","0773e78b":"87760","73ca4188":"88048",c2237e68:"88131","504d78e0":"88494","801276a1":"88495","51c7df8c":"88790","45926b62":"88843","95ec96e5":"88946","4b6eee9a":"89598",cc180519:"90049","869d42f3":"90381","07006f9e":"90642","098f2604":"90780","468d57a9":"91131","227d1fc4":"91258",a0aa5253:"91395","32b8fafb":"92113","4951b372":"92170",cd64d641:"92687","8093477b":"92811",bc69c5bc:"92896",c342bcae:"93036",b0f19176:"93087","26398b18":"93842",c7507218:"94594",da19ecb4:"94642",dd31e7e9:"94725",da071cb8:"94811",c75d145e:"95191","94f11012":"95409","19a6be06":"96449","8d02075b":"96815","4eee9c87":"96991","31b73615":"97191",reactPlayerFilePlayer:"97458","50a12feb":"97499",ac5db01d:"97785","819b642a":"98042","5a96e453":"98175",ae22b856:"98498","44a83f6a":"98548","65c67349":"98996","08aab21d":"99094","32ebcda7":"99180",reactPlayerWistia:"99340",a1154d73:"99341",e0bec135:"99591","51ddac88":"99989"}[e]||e,t.p+t.u(e)},(()=>{var e={45354:0,71869:0};t.f.j=(a,c)=>{var f=t.o(e,a)?e[a]:void 0;if(0!==f)if(f)c.push(f[2]);else if(/^(45354|71869)$/.test(a))e[a]=0;else{var d=new Promise(((c,d)=>f=e[a]=[c,d]));c.push(f[2]=d);var b=t.p+t.u(a),r=new Error;t.l(b,(c=>{if(t.o(e,a)&&(0!==(f=e[a])&&(e[a]=void 0),f)){var d=c&&("load"===c.type?"missing":c.type),b=c&&c.target&&c.target.src;r.message="Loading chunk "+a+" failed.\n("+d+": "+b+")",r.name="ChunkLoadError",r.type=d,r.request=b,f[1](r)}}),"chunk-"+a,a)}},t.O.j=a=>0===e[a];var a=(a,c)=>{var f,d,b=c[0],r=c[1],o=c[2],l=0;if(b.some((a=>0!==e[a]))){for(f in r)t.o(r,f)&&(t.m[f]=r[f]);if(o)var n=o(t)}for(a&&a(c);l{"use strict";var e,a,c,f,d,b={},r={};function t(e){var a=r[e];if(void 0!==a)return a.exports;var c=r[e]={exports:{}};return b[e].call(c.exports,c,c.exports,t),c.exports}t.m=b,e=[],t.O=(a,c,f,d)=>{if(!c){var b=1/0;for(n=0;n=d)&&Object.keys(t.O).every((e=>t.O[e](c[o])))?c.splice(o--,1):(r=!1,d0&&e[n-1][2]>d;n--)e[n]=e[n-1];e[n]=[c,f,d]},t.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return t.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,t.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var d=Object.create(null);t.r(d);var b={};a=a||[null,c({}),c([]),c(c)];for(var r=2&f&&e;"object"==typeof r&&!~a.indexOf(r);r=c(r))Object.getOwnPropertyNames(r).forEach((a=>b[a]=()=>e[a]));return b.default=()=>e,t.d(d,b),d},t.d=(e,a)=>{for(var c in a)t.o(a,c)&&!t.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},t.f={},t.e=e=>Promise.all(Object.keys(t.f).reduce(((a,c)=>(t.f[c](e,a),a)),[])),t.u=e=>"assets/js/"+({456:"cb867d98",565:"3f04b2f3",762:"cdc118a8",1160:"638e38ae",1171:"b685e31b",1572:"02c0cfe0",1705:"1921e4ca",1832:"bdc5a52e",1923:"b32c213b",1970:"dbf9e27d",2278:"27e827f8",2295:"0a5c01b2",2496:"3874f1bf",2730:"ac6e050c",3202:"8e7261c9",3230:"9d217e1f",3249:"05ec9480",3392:"reactPlayerVidyard",3607:"d8d6d57b",3783:"a6c3ea4a",3877:"79840965",3900:"ecb3c634",4272:"17dc776d",4276:"7a3d47b3",4499:"f149b10e",4550:"e3443ce0",4574:"976a2d80",4645:"9644aa4e",5e3:"da698f4c",5344:"8baf194b",5352:"52f87500",5441:"af1c5d2b",5623:"10ad1fa6",5819:"e4a796aa",5827:"3d277f18",5885:"3e4a4cb2",6157:"cce58fe7",6215:"f3467f26",6262:"27b43779",6265:"46b54090",6308:"2890c80c",6463:"reactPlayerKaltura",6486:"2e1ee4ed",6497:"5112ebe3",6615:"7b06977d",6918:"89b55a09",7161:"19e323d1",7267:"2db5c390",7606:"7517a61c",7701:"c2b45dbb",7785:"95bf5f56",8271:"94b2bc9a",8349:"06a408fe",8500:"4c5c4c2e",8734:"82e43b76",8927:"b8787c81",9264:"1caa8cdb",9524:"daec0d60",9606:"4519f039",9640:"5589c54d",9647:"5e95c892",9671:"e64edb60",9837:"5a0a1617",10348:"fca5fdb4",10700:"313c9eb1",10845:"5c1eff22",10907:"f7ae65ac",11139:"dc7352a7",11184:"8af032d3",11301:"f584139f",11567:"22dd74f7",11607:"ef2492df",11784:"45dd886d",11934:"b809d820",11965:"1457ddcd",12007:"90ec8c6b",12042:"reactPlayerTwitch",12237:"b6f81eaa",12716:"d2aa311d",12766:"4934de22",12827:"28967b3e",13018:"076cf272",13019:"d3938b1f",13455:"5839343c",13535:"e84b4e80",13585:"ea237062",13650:"2d11a680",14237:"95a5d2b2",14715:"fc8c8cde",14936:"7c8e5227",15066:"fe3f3783",15246:"83c6f999",15447:"30bd0f5b",16328:"reactPlayerDailyMotion",16602:"616631fd",16678:"710ac1c1",16869:"444a6d4e",16884:"4ed1e0ac",16945:"5596dd05",17021:"828ace52",17209:"f9bde383",17289:"45939ed5",17320:"55f37562",17776:"070c8c93",17820:"ebd05845",18093:"0841186f",18401:"17896441",18446:"reactPlayerYouTube",19049:"2fca5c64",19738:"87ab7385",20033:"986f0f98",20210:"68401255",20423:"22f51758",20515:"704545ab",20681:"e66f2658",20773:"d4fc3158",20826:"4ab30eec",21611:"82444e58",21983:"57012fa6",22422:"d3af5b3c",22451:"f5a589e7",22611:"59df87e8",22750:"141135bb",23321:"676f1bdb",23452:"5af30237",23453:"ed64c12e",23619:"f6affd6e",23870:"956829f8",24078:"ec91ff36",24158:"1d39c85d",24295:"96523456",24832:"02e41de2",25362:"5bc657fa",25427:"3edac44d",25504:"0f2c2e36",25666:"522ca66b",25691:"9a594c98",25692:"7ca2e59a",26173:"reactPlayerVimeo",26376:"431ffdb5",26499:"a4adf53f",26622:"d9107a6a",27168:"7ac69e68",27350:"65e04ea3",27646:"12407b36",27685:"6aee17c2",27740:"38e32826",28235:"965931d7",29248:"4a49065b",29250:"dec2bd4a",29436:"dc8c27bd",29773:"1a84c7fd",30248:"b1218054",30418:"6feb7661",30473:"3141060a",30528:"1323771c",30765:"85d514f3",30799:"1a39ee04",30941:"4aa94ec1",31165:"926056c1",31267:"08d55cf7",31471:"3f80bb14",31474:"564db590",31727:"2e18ba50",32055:"9037180b",32096:"c090764b",32141:"df1414bb",32163:"3d150a24",32178:"16116660",32406:"5cde491b",32461:"a6311318",32492:"4e689a0b",32504:"7de3e81f",32741:"d9e7b984",32759:"7800d508",32944:"272aa200",33048:"25c6d77a",33098:"71ba2dc1",33460:"9107c65f",33577:"a32c313f",33992:"cbf3c4ec",34321:"6f56eca8",34438:"54cab4d4",34662:"cf3c245e",34726:"1b6591f7",34750:"07e708e9",34935:"6da448d1",34975:"ff5ed6ba",35223:"db7d4591",35540:"ce86e3e6",35563:"e7977816",35654:"dc4059b2",35742:"aba21aa0",35748:"1312139a",35884:"9c9052d1",36058:"a2a1c245",36132:"e8f4756d",36353:"reactPlayerPreview",36731:"bd568e77",36886:"8abbb0ee",36920:"ed772d97",37107:"3817c387",37296:"a2757506",37516:"9f1829f0",37710:"abd13aa2",37850:"b28bd8b1",37990:"441fd5fc",38031:"8ee9837e",38419:"bd6f2233",38471:"caf7731d",38527:"5e7d099e",38610:"c868bccf",38691:"036b5431",38717:"897331c0",38792:"4f0519c7",38853:"fc67ad3d",38864:"fac0eceb",39026:"c7156cf2",39056:"5f6b1733",39080:"511f9951",39408:"fe2e2e26",39431:"cdd4a9c6",39482:"327b0a57",39558:"50f2f9f3",39757:"9e0c2c37",39911:"92466816",40271:"6a734661",40374:"b5dcbe95",40563:"39dec3ba",40575:"33c1d41a",41237:"88a48c42",41507:"16b03284",41865:"fe76eed8",42083:"4048090e",42206:"91aed80e",42434:"5b2d7e3c",42800:"3aa0ab0a",42901:"2115313f",43174:"6ba85e75",43246:"2d16d24d",43444:"d2f6d210",43773:"a81cb65f",43848:"44145933",43888:"ad61550a",43903:"8186ecf9",44046:"5d707891",44486:"c0650537",44602:"69fcd2fc",44609:"c5313007",44630:"65b7208a",44816:"36fcb744",44947:"39ec0930",45141:"b1394c86",45268:"ef4456b5",45295:"f29fc884",45474:"79d28454",45655:"4a55fe3a",45724:"8dfd8953",45742:"c377a04b",46119:"d58f1ee2",46364:"fe522f67",46563:"aeef55f7",46688:"ac3101e9",46921:"d0b9ca74",46961:"2bbc2deb",47120:"dcbfe205",47127:"999788b8",47264:"b9ec56c8",47341:"7f0714d1",47527:"93dcedec",47627:"reactPlayerStreamable",47719:"b7ea99f7",48124:"8f509517",48134:"356ce494",48235:"df15bc7d",48276:"b467d32a",48436:"f6adf820",48552:"954e932f",48579:"566f49fb",48665:"0f4a5c74",49316:"510b9307",49406:"b26210db",49455:"c8139b75",49658:"0d76317c",49921:"fc8b5a5d",50041:"ac002d2b",50404:"98f4e1ec",50765:"bf519c8d",50908:"3fbaac07",51143:"fc6f07d2",51205:"db42f242",51349:"4aec9039",51379:"17f04a83",51637:"81e4ed6a",51780:"eecc43ff",52302:"e7ee6027",52365:"280af06a",52529:"e3d58533",52723:"reactPlayerMux",53084:"23975af2",53148:"9b4ab8cd",53357:"1577f7ed",53774:"53998120",54049:"4867e743",54220:"092bf57d",54530:"a271ef09",54582:"984d6493",54905:"98d962c5",55011:"49145cdf",55388:"b2419a00",55664:"169f3d24",56264:"46eeb6cb",56282:"d636c09f",56383:"ecaa7076",56420:"fd4b36bb",56684:"378935ce",56764:"805a59dc",57035:"f527bef3",57356:"bb9c591b",57694:"21b7a589",57790:"1b218eaa",57869:"a7edc2bd",58022:"c134ef8a",58215:"1111b27e",58718:"afb7a97b",58800:"5144cf5e",59075:"6e29a506",59221:"76259cc3",59332:"857097c6",59409:"a64b2578",59599:"1e1f8072",59600:"ac9d9d69",59949:"5c6f6ba9",60365:"bd118f84",60759:"719163ad",60880:"640696ee",60886:"c10a0985",60893:"6fbf0c67",60908:"0eebd274",61114:"3cc71396",61252:"3b66921f",61273:"099a3596",61291:"d38e3f9f",61358:"3d1ae229",61368:"f28f059c",61505:"e58556b2",61977:"7570de64",62059:"0893faed",62134:"0d7acd84",62357:"6d2a4d3f",62362:"44463284",62573:"bd1cffff",62921:"1d7c691c",62929:"f5fed352",63474:"98c94590",63538:"06393fc1",63706:"2b67eda4",63737:"53e9dd7a",63747:"fb72d7b2",63960:"a6397568",64558:"b91fbf2a",64641:"eac16e1d",64651:"4c781063",64665:"6f44ab90",65110:"063d75bd",65142:"eb4c176e",65433:"616bfcf6",65542:"af754a1f",65655:"1ebbfca8",65755:"bafd283f",65784:"90239e6e",65866:"419cd6b8",66225:"9f8e6d57",66339:"03b2528f",66811:"3e87058f",66850:"0c695afe",66868:"3c4af576",66885:"5e253f2f",66929:"da54b976",67068:"ae0eacdd",67098:"a7bd4aaa",67217:"726a6c22",67349:"61ff6850",67458:"0d271e1e",67532:"49fed513",67570:"reactPlayerMixcloud",67714:"9d7352c0",68230:"3cf6fa35",68364:"812775a4",68391:"24557dbc",68700:"96331245",68874:"10ea0b82",68912:"2c2832e4",68915:"62de5d73",68960:"358c2507",68962:"af68ae04",69050:"4ac2e930",69779:"3c9432f0",69816:"20d56cb7",69891:"62037464",69979:"reactPlayerSoundCloud",70326:"c3373259",70934:"d44e0d1c",71247:"308471de",71383:"087cd58c",71826:"a4c89d62",71907:"86a8bb6c",71967:"4fa4eafa",72074:"71319bec",72132:"83ac10ed",72231:"fe170cc9",72561:"adce8179",73107:"646cbece",73379:"9d779d8b",73932:"2020ed93",73939:"2ed96714",74081:"ce4dbf6d",74583:"4bfca71d",74780:"ebde045d",74834:"d26a73b8",74860:"00d14154",75412:"5390e21f",75702:"307525ba",75822:"2db99065",75868:"071f33a8",75965:"b48f41b9",76093:"7d63aba8",76224:"03b3cfd2",76238:"8615e055",76372:"d802bb56",76768:"8bed5a26",76973:"78ae7ec8",77137:"42abcd4d",77313:"ee65edec",77318:"67e77328",77757:"f6f476f1",78007:"8eead450",78416:"068743c8",78631:"b7b014bf",78702:"82ea7079",79048:"a94703ab",79052:"6d717251",79225:"526e379a",79354:"4118187a",79825:"2d4af3bf",79956:"9e09f891",79983:"a7f483d1",80549:"afde3230",80721:"05fa9a60",81509:"4ead9a95",81657:"f8189ec4",81790:"42a9b3c5",81849:"2e3fc0f9",82075:"056b386b",82201:"18910d94",82261:"0c6fe626",82439:"e4eafb12",82477:"2ca08277",83287:"7af31c45",83752:"efe5610c",83943:"9c5d9512",84219:"51e50f95",84331:"79e0e7f1",84605:"8552f549",84656:"813cfb2f",84750:"aefdd881",84850:"bc03f89b",85462:"9270ba4f",85527:"5143312c",85528:"21e10cde",85556:"21a4ba71",85943:"05fbef88",86012:"da202fdd",86037:"eaeab60b",86057:"9fbfaf6d",86106:"1877d9d5",86298:"e2d6ba1f",86886:"7b33c27b",86887:"reactPlayerFacebook",86992:"3fe65583",87012:"869ae8a7",87126:"b916a1ab",87402:"c3094240",87510:"9d36f238",87760:"0773e78b",88048:"73ca4188",88131:"c2237e68",88494:"504d78e0",88495:"801276a1",88790:"51c7df8c",88843:"45926b62",88946:"95ec96e5",89598:"4b6eee9a",90049:"cc180519",90381:"869d42f3",90642:"07006f9e",90780:"098f2604",91131:"468d57a9",91258:"227d1fc4",91395:"a0aa5253",92113:"32b8fafb",92170:"4951b372",92687:"cd64d641",92811:"8093477b",92896:"bc69c5bc",93036:"c342bcae",93087:"b0f19176",93842:"26398b18",94594:"c7507218",94642:"da19ecb4",94725:"dd31e7e9",94811:"da071cb8",95191:"c75d145e",95409:"94f11012",96449:"19a6be06",96815:"8d02075b",96991:"4eee9c87",97191:"31b73615",97458:"reactPlayerFilePlayer",97499:"50a12feb",97785:"ac5db01d",98042:"819b642a",98116:"49849746",98175:"5a96e453",98498:"ae22b856",98548:"44a83f6a",98601:"13798859",98996:"65c67349",99094:"08aab21d",99180:"32ebcda7",99340:"reactPlayerWistia",99341:"a1154d73",99591:"e0bec135",99989:"51ddac88"}[e]||e)+"."+{456:"5c30ecdd",565:"94a09b6c",762:"df50c981",1160:"918efc1f",1171:"de34cd0e",1572:"ffbe0cfc",1705:"038460b6",1832:"9614689c",1923:"cb2bc5be",1970:"cac2a9b8",2278:"d475be2b",2295:"e81bbf25",2496:"b540b729",2730:"923b54e1",3202:"f35694a9",3230:"4129121e",3249:"82c7846c",3392:"8464e17b",3607:"2981ded1",3783:"71a2f8e8",3877:"58749100",3900:"0ba32b97",4272:"0900e2a1",4276:"8faf83a5",4499:"ca8d1432",4550:"46f5f770",4574:"1c78d390",4645:"e160e737",5e3:"e340e97d",5344:"1d1077a2",5352:"5ee75c06",5441:"151c62bf",5623:"9548c1a1",5819:"a4a89c82",5827:"5cc9996e",5885:"fcb3bbcb",6157:"dd0a4d50",6215:"51944600",6262:"794fd95d",6265:"83c21074",6308:"350484bc",6463:"bec1a06c",6486:"4b0eb0a1",6497:"42707b0b",6615:"7db76aa6",6918:"031ec4ab",7161:"2c411627",7267:"ce74b45c",7606:"45b626ad",7701:"316b1161",7785:"f569d217",8271:"bce6ddee",8349:"03f95123",8500:"a390a5ca",8734:"2de05990",8927:"f986535a",9264:"6ae52032",9524:"e7c42f6f",9606:"bff55b72",9640:"b703cc22",9647:"cac24016",9671:"0a30cd6c",9837:"ede23a01",10348:"ec8b3811",10700:"708d8037",10845:"2bc04da3",10907:"eb9d65c3",11139:"303df097",11184:"9d69cbad",11301:"8387b5bf",11567:"432c7b35",11607:"b64b2d67",11784:"9d3408ab",11934:"da61538a",11965:"d6e5dd4d",12007:"fb425a62",12042:"a0c42814",12237:"8a850fa6",12716:"faed95e1",12766:"97abbc05",12827:"144f3020",13018:"c5ad98c6",13019:"c5e3aef7",13455:"1451755d",13535:"88a06537",13585:"a746e017",13650:"62810914",14237:"8c2a2bc3",14715:"95abf808",14936:"6ee147d1",15066:"38ece79e",15246:"fd5943dc",15447:"82977fde",16328:"4fa8d3c8",16602:"f2bf07f8",16678:"cb38a105",16869:"995c6ef6",16884:"bf9abfa1",16945:"1eaf58e9",17021:"6c74822a",17209:"e94a64b5",17289:"e2e7eec1",17320:"9ddeadd7",17776:"f89fd2b8",17820:"623e6e0e",18093:"d4afddde",18401:"30c4f83a",18446:"150ff8a0",19049:"08036f4e",19738:"a816c680",20033:"fa674d6a",20210:"4ea135dd",20423:"076d2946",20515:"85d707fe",20681:"7e97a650",20773:"a2cebc00",20826:"8b874cbc",21611:"6e533a7e",21983:"f9a941e2",22422:"feb00a9e",22451:"ef972e5e",22611:"18587ae4",22750:"a52908e5",23321:"84054f56",23452:"ebba4448",23453:"2ff5cbe7",23619:"c27273de",23870:"3742bfab",24078:"730ca41c",24158:"ce6a000b",24295:"4aae9b71",24832:"af6b73df",25362:"f0170814",25427:"3244da9c",25504:"28938478",25666:"2f0c77bf",25691:"426557b6",25692:"585ab289",26173:"076fef9c",26376:"a1f11cb7",26499:"dd7640ab",26622:"f0629b1b",27168:"e3dc9e21",27350:"5fd6e6d7",27646:"0678c8f9",27685:"f20ffda9",27740:"8f7d4d98",28235:"f6cbcccb",29248:"d7c12529",29250:"925abd2b",29436:"7ca95c22",29773:"b8c6f670",30248:"0ad8a16e",30418:"5fc7b2a0",30473:"0abc4692",30528:"435813db",30765:"d86090af",30799:"388c9414",30941:"49876b37",31165:"02614496",31267:"933156b4",31471:"450344fc",31474:"dbbf8152",31727:"d3f3b0b1",32055:"a95bfc3b",32096:"04828676",32141:"bcdc361b",32163:"70936a3c",32178:"36e60316",32406:"bd1dc0ac",32461:"6b4a958d",32492:"30cd7c7f",32504:"754ac7de",32741:"552767cd",32759:"d8e2798a",32944:"6f349f74",33048:"1a010730",33098:"480f07f7",33460:"8f3f92e4",33577:"ce38b0c8",33992:"a7260a35",34321:"ab8e5c20",34438:"8f46a7dd",34662:"8da76618",34726:"90739fe9",34750:"13529313",34935:"59f5597e",34975:"41c5c4bb",35223:"2367e813",35540:"daa770e8",35563:"22b8fd33",35654:"72cb9c74",35742:"e08a145a",35748:"816249d7",35884:"a0bf4e6b",36058:"b63b94d9",36132:"75cbf3f9",36353:"4de9bab6",36731:"1ab1d6ee",36886:"9c9e515a",36920:"3a69befa",37107:"f19c047b",37296:"20763684",37516:"2ab4897d",37710:"5cf4ff57",37850:"ed2f760b",37990:"fa9f8a31",38031:"396006c8",38419:"a12c2499",38471:"93b2d4dd",38527:"73056614",38610:"37df5efb",38691:"137dc0f8",38717:"6dbb7b59",38792:"7deb9f3e",38853:"5c9e45fe",38864:"4813ef31",39026:"f2f8a69b",39056:"60f70f39",39080:"b0c77b48",39408:"88db313c",39431:"2bcf2e6d",39482:"7e3b08ef",39503:"18fac5cf",39558:"41945f10",39757:"47703e3b",39911:"646e7dec",40271:"f790e023",40374:"179979e4",40563:"94247613",40575:"4d0b112e",41237:"3bbdf534",41507:"77c30778",41865:"c835f8b0",42083:"2aff9481",42206:"18d5693f",42434:"1f6d6607",42800:"bf6545c0",42901:"2fdbe13a",43174:"013544f4",43246:"ddc98077",43444:"cff02423",43773:"3cc7db7d",43848:"57247e24",43888:"d74ff318",43903:"41a52d13",44046:"a946825c",44486:"28ccbcec",44602:"aaf93cb1",44609:"32c1fd2c",44630:"f2d8976e",44816:"0e7f93b4",44947:"a24467f3",45141:"e3968051",45268:"7006193f",45295:"b0715bed",45474:"1abec566",45655:"c2164e90",45724:"b59ddc1b",45742:"2497dd34",46119:"7805de88",46364:"fdfddfc0",46563:"2e6253c5",46688:"a1d131c8",46921:"260d54e0",46961:"94b493aa",47120:"723a0b3e",47127:"de5390c4",47264:"44b44216",47341:"18ca620e",47527:"d950e87e",47627:"bb35fa43",47719:"646275e7",48124:"55af4038",48134:"b6137268",48235:"bc75728e",48276:"231a1e55",48436:"89305d4a",48552:"c704b5f4",48579:"bbd9e592",48665:"b81074e2",49316:"5e345ac8",49406:"a3ecaee8",49455:"15c58fe1",49658:"3da918b0",49921:"f2c2a1f0",50041:"f7cb55c7",50404:"eb1ab0f9",50765:"479f1916",50908:"a5b524ad",51143:"136727d9",51205:"ee2e77cb",51349:"1e076875",51379:"27ea6246",51637:"ffb79940",51780:"ce9149be",52302:"340b0e6b",52365:"d23ef6a9",52529:"e7cefacb",52723:"3e4df075",53084:"315da40f",53148:"4212deb6",53357:"b5a1c415",53774:"72126425",54049:"4089600b",54220:"d4f185d8",54530:"0bd12311",54582:"4e5700b0",54905:"feb41c26",55011:"95879cb0",55388:"33179a2f",55664:"258a4e6b",56264:"6318e439",56282:"b46c91af",56383:"1ff19ca5",56420:"1972625f",56684:"ab8eab18",56764:"ac5b41d7",57035:"ad79c7ab",57356:"42441995",57694:"a34951a6",57790:"4a46f698",57869:"89931416",58022:"7b3238f1",58215:"5be13c8d",58718:"a820c36e",58800:"e98ceb1d",59075:"25749229",59221:"658e6207",59332:"84712487",59409:"be73a79d",59599:"780630f8",59600:"ca1b31c5",59949:"0c457c29",60365:"1fd2fa70",60759:"d322d307",60880:"f6ba7287",60886:"67c47b8d",60893:"fe1ea3f9",60908:"e76a5e92",61114:"46cf560e",61252:"0ab3ec6f",61273:"05750299",61291:"0f509abf",61358:"9defced7",61368:"88200516",61505:"1a21d780",61977:"3a915ac8",62059:"27a610be",62134:"136bb77a",62357:"dd821bdf",62362:"8db1be48",62573:"09b3ebf3",62921:"9d42f085",62929:"c76283aa",63474:"bb220697",63538:"7b7f0e14",63706:"6f94bc8f",63737:"af78b6a2",63747:"7c5b8fbd",63960:"9f0fe283",64558:"25e0c733",64641:"4002d9f9",64651:"7df9a0dc",64665:"b140ef8f",65110:"0c2123d1",65142:"d226848c",65433:"d959ad9b",65542:"a7c67c53",65655:"3f647a48",65755:"c46f5968",65784:"b94d85b3",65866:"f9e10c84",66225:"f10f224f",66339:"800c2e61",66811:"945f99d9",66850:"7753ee7f",66868:"65080ded",66885:"1bd3e9c3",66929:"d218d95f",67068:"046fc798",67098:"03929b29",67217:"c9c29188",67349:"b94a3a6a",67458:"f760b356",67532:"60df9b16",67570:"12aff88e",67714:"973cd9fc",68230:"835eaee7",68364:"53e94f68",68391:"262895ce",68700:"64fe7812",68874:"d1febe02",68912:"0c81f713",68915:"57e00474",68960:"18b5e3ad",68962:"d845c0a4",69050:"358b5513",69779:"faba2980",69816:"58af7b00",69891:"80af80ae",69979:"f8f19bc3",70326:"fafebdcb",70934:"73854ef9",71247:"5a63971c",71383:"75b257bc",71826:"9f1c6fe5",71907:"0751c0f3",71967:"1af4694c",72074:"522fdb31",72132:"6e4054d2",72231:"e3c174bf",72561:"1f9fbc90",73107:"ecc6be9c",73379:"16b17994",73932:"b35fd796",73939:"aba6bb06",74081:"b57cba4e",74583:"ce4c9b2f",74780:"b7d71cb3",74834:"15357603",74860:"426c5862",75412:"d72a934a",75702:"3926a131",75822:"1d9852b1",75868:"3118d0c9",75965:"19020673",76093:"8e28eeb6",76224:"8f29238e",76238:"a738aae6",76372:"297afbc9",76768:"c3ca6e24",76973:"a72e321d",77137:"daff0432",77313:"b92d7b2e",77318:"44e1adab",77757:"eb1c1544",78007:"2b6a8f00",78416:"2ad246f2",78631:"b6f33b62",78702:"ed155bd3",79048:"0f54d2a9",79052:"634be361",79225:"bad5b331",79354:"d6957fa9",79825:"8c4cf900",79956:"4d5ec1eb",79983:"52b6f63f",80549:"a1b3777a",80721:"cdf43ae5",81509:"5a98113a",81657:"d230bb30",81790:"c56f6a89",81849:"0f44253c",82075:"7a5a588a",82201:"c855be90",82237:"787c04ec",82261:"2fc96e72",82439:"18a56b6c",82477:"12d174de",83287:"084dde1a",83752:"d91cc53e",83943:"a64bf43a",84219:"d24c437b",84331:"b37577e8",84605:"8cf0495c",84656:"73c53ede",84750:"1857e769",84850:"f287e029",85462:"ddca2c18",85527:"3afd894d",85528:"74b87448",85556:"fee97575",85943:"e5b4cdd6",86012:"ab7bdaa5",86037:"04050011",86057:"db95e34c",86106:"1290858d",86298:"92e42ef4",86886:"dad3b87b",86887:"508da014",86992:"82004d70",87012:"fd4f4b30",87126:"89adbb17",87402:"abdfd46c",87510:"720f0f93",87760:"72f8f4bb",88048:"2a1833d8",88131:"e11652fa",88494:"7d33658e",88495:"efabda4c",88790:"c5a360b0",88843:"ba8ab281",88946:"350ed3aa",89598:"30bcd67d",90049:"70470979",90381:"4acaccf6",90642:"83acf9a9",90780:"75e3e359",91131:"759062e1",91258:"0a10d55b",91395:"31f57203",92113:"439ef5f1",92170:"f7b1e9bd",92687:"bed1a1d3",92811:"8a204457",92896:"b265749e",93036:"7c8d08ac",93087:"0090bbd7",93842:"d418eca4",94594:"42c52295",94642:"c0efeaa4",94725:"7118b112",94811:"933445a7",95191:"0ee87f70",95409:"6f87b63a",96449:"9cfed380",96815:"362b1a69",96991:"eca5cf70",97191:"ca75b3a5",97458:"036de6e1",97499:"1a4e721e",97785:"bf926c46",98042:"14a96714",98116:"a22cb511",98175:"b8bdaaeb",98498:"1128c3c9",98548:"0250dbf6",98601:"75b6fdce",98996:"433b1eca",99094:"54319916",99180:"e5d0a4e7",99340:"c5c0cf6c",99341:"4403c816",99591:"4e74c25b",99989:"1ffc7914"}[e]+".js",t.miniCssF=e=>{},t.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),t.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),f={},d="serverpod-docs:",t.l=(e,a,c,b)=>{if(f[e])f[e].push(a);else{var r,o;if(void 0!==c)for(var l=document.getElementsByTagName("script"),n=0;n{r.onerror=r.onload=null,clearTimeout(s);var d=f[e];if(delete f[e],r.parentNode&&r.parentNode.removeChild(r),d&&d.forEach((e=>e(c))),a)return a(c)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:r}),12e4);r.onerror=u.bind(null,r.onerror),r.onload=u.bind(null,r.onload),o&&document.head.appendChild(r)}},t.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.p="/",t.gca=function(e){return e={13798859:"98601",16116660:"32178",17896441:"18401",44145933:"43848",44463284:"62362",49849746:"98116",53998120:"53774",62037464:"69891",68401255:"20210",79840965:"3877",92466816:"39911",96331245:"68700",96523456:"24295",cb867d98:"456","3f04b2f3":"565",cdc118a8:"762","638e38ae":"1160",b685e31b:"1171","02c0cfe0":"1572","1921e4ca":"1705",bdc5a52e:"1832",b32c213b:"1923",dbf9e27d:"1970","27e827f8":"2278","0a5c01b2":"2295","3874f1bf":"2496",ac6e050c:"2730","8e7261c9":"3202","9d217e1f":"3230","05ec9480":"3249",reactPlayerVidyard:"3392",d8d6d57b:"3607",a6c3ea4a:"3783",ecb3c634:"3900","17dc776d":"4272","7a3d47b3":"4276",f149b10e:"4499",e3443ce0:"4550","976a2d80":"4574","9644aa4e":"4645",da698f4c:"5000","8baf194b":"5344","52f87500":"5352",af1c5d2b:"5441","10ad1fa6":"5623",e4a796aa:"5819","3d277f18":"5827","3e4a4cb2":"5885",cce58fe7:"6157",f3467f26:"6215","27b43779":"6262","46b54090":"6265","2890c80c":"6308",reactPlayerKaltura:"6463","2e1ee4ed":"6486","5112ebe3":"6497","7b06977d":"6615","89b55a09":"6918","19e323d1":"7161","2db5c390":"7267","7517a61c":"7606",c2b45dbb:"7701","95bf5f56":"7785","94b2bc9a":"8271","06a408fe":"8349","4c5c4c2e":"8500","82e43b76":"8734",b8787c81:"8927","1caa8cdb":"9264",daec0d60:"9524","4519f039":"9606","5589c54d":"9640","5e95c892":"9647",e64edb60:"9671","5a0a1617":"9837",fca5fdb4:"10348","313c9eb1":"10700","5c1eff22":"10845",f7ae65ac:"10907",dc7352a7:"11139","8af032d3":"11184",f584139f:"11301","22dd74f7":"11567",ef2492df:"11607","45dd886d":"11784",b809d820:"11934","1457ddcd":"11965","90ec8c6b":"12007",reactPlayerTwitch:"12042",b6f81eaa:"12237",d2aa311d:"12716","4934de22":"12766","28967b3e":"12827","076cf272":"13018",d3938b1f:"13019","5839343c":"13455",e84b4e80:"13535",ea237062:"13585","2d11a680":"13650","95a5d2b2":"14237",fc8c8cde:"14715","7c8e5227":"14936",fe3f3783:"15066","83c6f999":"15246","30bd0f5b":"15447",reactPlayerDailyMotion:"16328","616631fd":"16602","710ac1c1":"16678","444a6d4e":"16869","4ed1e0ac":"16884","5596dd05":"16945","828ace52":"17021",f9bde383:"17209","45939ed5":"17289","55f37562":"17320","070c8c93":"17776",ebd05845:"17820","0841186f":"18093",reactPlayerYouTube:"18446","2fca5c64":"19049","87ab7385":"19738","986f0f98":"20033","22f51758":"20423","704545ab":"20515",e66f2658:"20681",d4fc3158:"20773","4ab30eec":"20826","82444e58":"21611","57012fa6":"21983",d3af5b3c:"22422",f5a589e7:"22451","59df87e8":"22611","141135bb":"22750","676f1bdb":"23321","5af30237":"23452",ed64c12e:"23453",f6affd6e:"23619","956829f8":"23870",ec91ff36:"24078","1d39c85d":"24158","02e41de2":"24832","5bc657fa":"25362","3edac44d":"25427","0f2c2e36":"25504","522ca66b":"25666","9a594c98":"25691","7ca2e59a":"25692",reactPlayerVimeo:"26173","431ffdb5":"26376",a4adf53f:"26499",d9107a6a:"26622","7ac69e68":"27168","65e04ea3":"27350","12407b36":"27646","6aee17c2":"27685","38e32826":"27740","965931d7":"28235","4a49065b":"29248",dec2bd4a:"29250",dc8c27bd:"29436","1a84c7fd":"29773",b1218054:"30248","6feb7661":"30418","3141060a":"30473","1323771c":"30528","85d514f3":"30765","1a39ee04":"30799","4aa94ec1":"30941","926056c1":"31165","08d55cf7":"31267","3f80bb14":"31471","564db590":"31474","2e18ba50":"31727","9037180b":"32055",c090764b:"32096",df1414bb:"32141","3d150a24":"32163","5cde491b":"32406",a6311318:"32461","4e689a0b":"32492","7de3e81f":"32504",d9e7b984:"32741","7800d508":"32759","272aa200":"32944","25c6d77a":"33048","71ba2dc1":"33098","9107c65f":"33460",a32c313f:"33577",cbf3c4ec:"33992","6f56eca8":"34321","54cab4d4":"34438",cf3c245e:"34662","1b6591f7":"34726","07e708e9":"34750","6da448d1":"34935",ff5ed6ba:"34975",db7d4591:"35223",ce86e3e6:"35540",e7977816:"35563",dc4059b2:"35654",aba21aa0:"35742","1312139a":"35748","9c9052d1":"35884",a2a1c245:"36058",e8f4756d:"36132",reactPlayerPreview:"36353",bd568e77:"36731","8abbb0ee":"36886",ed772d97:"36920","3817c387":"37107",a2757506:"37296","9f1829f0":"37516",abd13aa2:"37710",b28bd8b1:"37850","441fd5fc":"37990","8ee9837e":"38031",bd6f2233:"38419",caf7731d:"38471","5e7d099e":"38527",c868bccf:"38610","036b5431":"38691","897331c0":"38717","4f0519c7":"38792",fc67ad3d:"38853",fac0eceb:"38864",c7156cf2:"39026","5f6b1733":"39056","511f9951":"39080",fe2e2e26:"39408",cdd4a9c6:"39431","327b0a57":"39482","50f2f9f3":"39558","9e0c2c37":"39757","6a734661":"40271",b5dcbe95:"40374","39dec3ba":"40563","33c1d41a":"40575","88a48c42":"41237","16b03284":"41507",fe76eed8:"41865","4048090e":"42083","91aed80e":"42206","5b2d7e3c":"42434","3aa0ab0a":"42800","2115313f":"42901","6ba85e75":"43174","2d16d24d":"43246",d2f6d210:"43444",a81cb65f:"43773",ad61550a:"43888","8186ecf9":"43903","5d707891":"44046",c0650537:"44486","69fcd2fc":"44602",c5313007:"44609","65b7208a":"44630","36fcb744":"44816","39ec0930":"44947",b1394c86:"45141",ef4456b5:"45268",f29fc884:"45295","79d28454":"45474","4a55fe3a":"45655","8dfd8953":"45724",c377a04b:"45742",d58f1ee2:"46119",fe522f67:"46364",aeef55f7:"46563",ac3101e9:"46688",d0b9ca74:"46921","2bbc2deb":"46961",dcbfe205:"47120","999788b8":"47127",b9ec56c8:"47264","7f0714d1":"47341","93dcedec":"47527",reactPlayerStreamable:"47627",b7ea99f7:"47719","8f509517":"48124","356ce494":"48134",df15bc7d:"48235",b467d32a:"48276",f6adf820:"48436","954e932f":"48552","566f49fb":"48579","0f4a5c74":"48665","510b9307":"49316",b26210db:"49406",c8139b75:"49455","0d76317c":"49658",fc8b5a5d:"49921",ac002d2b:"50041","98f4e1ec":"50404",bf519c8d:"50765","3fbaac07":"50908",fc6f07d2:"51143",db42f242:"51205","4aec9039":"51349","17f04a83":"51379","81e4ed6a":"51637",eecc43ff:"51780",e7ee6027:"52302","280af06a":"52365",e3d58533:"52529",reactPlayerMux:"52723","23975af2":"53084","9b4ab8cd":"53148","1577f7ed":"53357","4867e743":"54049","092bf57d":"54220",a271ef09:"54530","984d6493":"54582","98d962c5":"54905","49145cdf":"55011",b2419a00:"55388","169f3d24":"55664","46eeb6cb":"56264",d636c09f:"56282",ecaa7076:"56383",fd4b36bb:"56420","378935ce":"56684","805a59dc":"56764",f527bef3:"57035",bb9c591b:"57356","21b7a589":"57694","1b218eaa":"57790",a7edc2bd:"57869",c134ef8a:"58022","1111b27e":"58215",afb7a97b:"58718","5144cf5e":"58800","6e29a506":"59075","76259cc3":"59221","857097c6":"59332",a64b2578:"59409","1e1f8072":"59599",ac9d9d69:"59600","5c6f6ba9":"59949",bd118f84:"60365","719163ad":"60759","640696ee":"60880",c10a0985:"60886","6fbf0c67":"60893","0eebd274":"60908","3cc71396":"61114","3b66921f":"61252","099a3596":"61273",d38e3f9f:"61291","3d1ae229":"61358",f28f059c:"61368",e58556b2:"61505","7570de64":"61977","0893faed":"62059","0d7acd84":"62134","6d2a4d3f":"62357",bd1cffff:"62573","1d7c691c":"62921",f5fed352:"62929","98c94590":"63474","06393fc1":"63538","2b67eda4":"63706","53e9dd7a":"63737",fb72d7b2:"63747",a6397568:"63960",b91fbf2a:"64558",eac16e1d:"64641","4c781063":"64651","6f44ab90":"64665","063d75bd":"65110",eb4c176e:"65142","616bfcf6":"65433",af754a1f:"65542","1ebbfca8":"65655",bafd283f:"65755","90239e6e":"65784","419cd6b8":"65866","9f8e6d57":"66225","03b2528f":"66339","3e87058f":"66811","0c695afe":"66850","3c4af576":"66868","5e253f2f":"66885",da54b976:"66929",ae0eacdd:"67068",a7bd4aaa:"67098","726a6c22":"67217","61ff6850":"67349","0d271e1e":"67458","49fed513":"67532",reactPlayerMixcloud:"67570","9d7352c0":"67714","3cf6fa35":"68230","812775a4":"68364","24557dbc":"68391","10ea0b82":"68874","2c2832e4":"68912","62de5d73":"68915","358c2507":"68960",af68ae04:"68962","4ac2e930":"69050","3c9432f0":"69779","20d56cb7":"69816",reactPlayerSoundCloud:"69979",c3373259:"70326",d44e0d1c:"70934","308471de":"71247","087cd58c":"71383",a4c89d62:"71826","86a8bb6c":"71907","4fa4eafa":"71967","71319bec":"72074","83ac10ed":"72132",fe170cc9:"72231",adce8179:"72561","646cbece":"73107","9d779d8b":"73379","2020ed93":"73932","2ed96714":"73939",ce4dbf6d:"74081","4bfca71d":"74583",ebde045d:"74780",d26a73b8:"74834","00d14154":"74860","5390e21f":"75412","307525ba":"75702","2db99065":"75822","071f33a8":"75868",b48f41b9:"75965","7d63aba8":"76093","03b3cfd2":"76224","8615e055":"76238",d802bb56:"76372","8bed5a26":"76768","78ae7ec8":"76973","42abcd4d":"77137",ee65edec:"77313","67e77328":"77318",f6f476f1:"77757","8eead450":"78007","068743c8":"78416",b7b014bf:"78631","82ea7079":"78702",a94703ab:"79048","6d717251":"79052","526e379a":"79225","4118187a":"79354","2d4af3bf":"79825","9e09f891":"79956",a7f483d1:"79983",afde3230:"80549","05fa9a60":"80721","4ead9a95":"81509",f8189ec4:"81657","42a9b3c5":"81790","2e3fc0f9":"81849","056b386b":"82075","18910d94":"82201","0c6fe626":"82261",e4eafb12:"82439","2ca08277":"82477","7af31c45":"83287",efe5610c:"83752","9c5d9512":"83943","51e50f95":"84219","79e0e7f1":"84331","8552f549":"84605","813cfb2f":"84656",aefdd881:"84750",bc03f89b:"84850","9270ba4f":"85462","5143312c":"85527","21e10cde":"85528","21a4ba71":"85556","05fbef88":"85943",da202fdd:"86012",eaeab60b:"86037","9fbfaf6d":"86057","1877d9d5":"86106",e2d6ba1f:"86298","7b33c27b":"86886",reactPlayerFacebook:"86887","3fe65583":"86992","869ae8a7":"87012",b916a1ab:"87126",c3094240:"87402","9d36f238":"87510","0773e78b":"87760","73ca4188":"88048",c2237e68:"88131","504d78e0":"88494","801276a1":"88495","51c7df8c":"88790","45926b62":"88843","95ec96e5":"88946","4b6eee9a":"89598",cc180519:"90049","869d42f3":"90381","07006f9e":"90642","098f2604":"90780","468d57a9":"91131","227d1fc4":"91258",a0aa5253:"91395","32b8fafb":"92113","4951b372":"92170",cd64d641:"92687","8093477b":"92811",bc69c5bc:"92896",c342bcae:"93036",b0f19176:"93087","26398b18":"93842",c7507218:"94594",da19ecb4:"94642",dd31e7e9:"94725",da071cb8:"94811",c75d145e:"95191","94f11012":"95409","19a6be06":"96449","8d02075b":"96815","4eee9c87":"96991","31b73615":"97191",reactPlayerFilePlayer:"97458","50a12feb":"97499",ac5db01d:"97785","819b642a":"98042","5a96e453":"98175",ae22b856:"98498","44a83f6a":"98548","65c67349":"98996","08aab21d":"99094","32ebcda7":"99180",reactPlayerWistia:"99340",a1154d73:"99341",e0bec135:"99591","51ddac88":"99989"}[e]||e,t.p+t.u(e)},(()=>{var e={45354:0,71869:0};t.f.j=(a,c)=>{var f=t.o(e,a)?e[a]:void 0;if(0!==f)if(f)c.push(f[2]);else if(/^(45354|71869)$/.test(a))e[a]=0;else{var d=new Promise(((c,d)=>f=e[a]=[c,d]));c.push(f[2]=d);var b=t.p+t.u(a),r=new Error;t.l(b,(c=>{if(t.o(e,a)&&(0!==(f=e[a])&&(e[a]=void 0),f)){var d=c&&("load"===c.type?"missing":c.type),b=c&&c.target&&c.target.src;r.message="Loading chunk "+a+" failed.\n("+d+": "+b+")",r.name="ChunkLoadError",r.type=d,r.request=b,f[1](r)}}),"chunk-"+a,a)}},t.O.j=a=>0===e[a];var a=(a,c)=>{var f,d,b=c[0],r=c[1],o=c[2],l=0;if(b.some((a=>0!==e[a]))){for(f in r)t.o(r,f)&&(t.m[f]=r[f]);if(o)var n=o(t)}for(a&&a(c);l Capabilities | Serverpod - + diff --git a/docs/concepts/authentication/basics.html b/docs/concepts/authentication/basics.html index 37e80b9f0..320a2cad3 100644 --- a/docs/concepts/authentication/basics.html +++ b/docs/concepts/authentication/basics.html @@ -4,7 +4,7 @@ The basics | Serverpod - + diff --git a/docs/concepts/authentication/custom-overrides.html b/docs/concepts/authentication/custom-overrides.html index 8a89d774e..96f82f422 100644 --- a/docs/concepts/authentication/custom-overrides.html +++ b/docs/concepts/authentication/custom-overrides.html @@ -4,7 +4,7 @@ Custom overrides | Serverpod - + diff --git a/docs/concepts/authentication/providers/apple.html b/docs/concepts/authentication/providers/apple.html index c32f9a016..6414f23da 100644 --- a/docs/concepts/authentication/providers/apple.html +++ b/docs/concepts/authentication/providers/apple.html @@ -4,7 +4,7 @@ Apple | Serverpod - + diff --git a/docs/concepts/authentication/providers/custom-providers.html b/docs/concepts/authentication/providers/custom-providers.html index 06f8a161f..694fcd606 100644 --- a/docs/concepts/authentication/providers/custom-providers.html +++ b/docs/concepts/authentication/providers/custom-providers.html @@ -4,7 +4,7 @@ Custom providers | Serverpod - + diff --git a/docs/concepts/authentication/providers/email.html b/docs/concepts/authentication/providers/email.html index 57385204b..16fc82218 100644 --- a/docs/concepts/authentication/providers/email.html +++ b/docs/concepts/authentication/providers/email.html @@ -4,7 +4,7 @@ Email | Serverpod - + diff --git a/docs/concepts/authentication/providers/firebase.html b/docs/concepts/authentication/providers/firebase.html index cbcd2a8f7..b392db5be 100644 --- a/docs/concepts/authentication/providers/firebase.html +++ b/docs/concepts/authentication/providers/firebase.html @@ -4,7 +4,7 @@ Firebase | Serverpod - + diff --git a/docs/concepts/authentication/providers/google.html b/docs/concepts/authentication/providers/google.html index acda14e79..776cd461a 100644 --- a/docs/concepts/authentication/providers/google.html +++ b/docs/concepts/authentication/providers/google.html @@ -4,7 +4,7 @@ Google | Serverpod - + diff --git a/docs/concepts/authentication/setup.html b/docs/concepts/authentication/setup.html index 6a3b90e23..5ebe68a52 100644 --- a/docs/concepts/authentication/setup.html +++ b/docs/concepts/authentication/setup.html @@ -4,7 +4,7 @@ Setup | Serverpod - + diff --git a/docs/concepts/authentication/working-with-users.html b/docs/concepts/authentication/working-with-users.html index 013eace4f..ff219256b 100644 --- a/docs/concepts/authentication/working-with-users.html +++ b/docs/concepts/authentication/working-with-users.html @@ -4,7 +4,7 @@ Working with users | Serverpod - + diff --git a/docs/concepts/backward-compatibility.html b/docs/concepts/backward-compatibility.html index fa6442a71..7e8312cac 100644 --- a/docs/concepts/backward-compatibility.html +++ b/docs/concepts/backward-compatibility.html @@ -4,7 +4,7 @@ Backward compatibility | Serverpod - + diff --git a/docs/concepts/caching.html b/docs/concepts/caching.html index c18c64338..011a32ef6 100644 --- a/docs/concepts/caching.html +++ b/docs/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/concepts/configuration.html b/docs/concepts/configuration.html index 039db2f2c..48ca0a1bc 100644 --- a/docs/concepts/configuration.html +++ b/docs/concepts/configuration.html @@ -4,7 +4,7 @@ Configurations | Serverpod - + diff --git a/docs/concepts/database/connection.html b/docs/concepts/database/connection.html index 86f79d57e..f620f420f 100644 --- a/docs/concepts/database/connection.html +++ b/docs/concepts/database/connection.html @@ -4,7 +4,7 @@ Connection | Serverpod - + diff --git a/docs/concepts/database/crud.html b/docs/concepts/database/crud.html index 2d2dc6e90..75fc9e103 100644 --- a/docs/concepts/database/crud.html +++ b/docs/concepts/database/crud.html @@ -4,7 +4,7 @@ CRUD | Serverpod - + diff --git a/docs/concepts/database/filter.html b/docs/concepts/database/filter.html index 3adaa7312..77e636321 100644 --- a/docs/concepts/database/filter.html +++ b/docs/concepts/database/filter.html @@ -4,7 +4,7 @@ Filter | Serverpod - + diff --git a/docs/concepts/database/indexing.html b/docs/concepts/database/indexing.html index e3e79551f..3d27162b7 100644 --- a/docs/concepts/database/indexing.html +++ b/docs/concepts/database/indexing.html @@ -4,7 +4,7 @@ Indexing | Serverpod - + diff --git a/docs/concepts/database/migrations.html b/docs/concepts/database/migrations.html index eb775bacc..6bea0bad6 100644 --- a/docs/concepts/database/migrations.html +++ b/docs/concepts/database/migrations.html @@ -4,7 +4,7 @@ Migrations | Serverpod - + diff --git a/docs/concepts/database/models.html b/docs/concepts/database/models.html index fb0a13484..b50e7f55c 100644 --- a/docs/concepts/database/models.html +++ b/docs/concepts/database/models.html @@ -4,7 +4,7 @@ Models | Serverpod - + diff --git a/docs/concepts/database/pagination.html b/docs/concepts/database/pagination.html index 547e2fb7d..6ca52950b 100644 --- a/docs/concepts/database/pagination.html +++ b/docs/concepts/database/pagination.html @@ -4,7 +4,7 @@ Pagination | Serverpod - + diff --git a/docs/concepts/database/raw-access.html b/docs/concepts/database/raw-access.html index 4d9a7918d..ee2834357 100644 --- a/docs/concepts/database/raw-access.html +++ b/docs/concepts/database/raw-access.html @@ -4,7 +4,7 @@ Raw access | Serverpod - + diff --git a/docs/concepts/database/relation-queries.html b/docs/concepts/database/relation-queries.html index 7f8bd4cf8..6cc4c7361 100644 --- a/docs/concepts/database/relation-queries.html +++ b/docs/concepts/database/relation-queries.html @@ -4,7 +4,7 @@ Relation queries | Serverpod - + diff --git a/docs/concepts/database/relations/many-to-many.html b/docs/concepts/database/relations/many-to-many.html index 1a525aaa5..9f1e7b063 100644 --- a/docs/concepts/database/relations/many-to-many.html +++ b/docs/concepts/database/relations/many-to-many.html @@ -4,7 +4,7 @@ Many-to-many | Serverpod - + diff --git a/docs/concepts/database/relations/modules.html b/docs/concepts/database/relations/modules.html index d3385101f..444a08172 100644 --- a/docs/concepts/database/relations/modules.html +++ b/docs/concepts/database/relations/modules.html @@ -4,7 +4,7 @@ Relations with modules | Serverpod - + diff --git a/docs/concepts/database/relations/one-to-many.html b/docs/concepts/database/relations/one-to-many.html index 83b92da8e..886efa5c8 100644 --- a/docs/concepts/database/relations/one-to-many.html +++ b/docs/concepts/database/relations/one-to-many.html @@ -4,7 +4,7 @@ One-to-many | Serverpod - + diff --git a/docs/concepts/database/relations/one-to-one.html b/docs/concepts/database/relations/one-to-one.html index 44b64e28a..2817ef72a 100644 --- a/docs/concepts/database/relations/one-to-one.html +++ b/docs/concepts/database/relations/one-to-one.html @@ -4,7 +4,7 @@ One-to-one | Serverpod - + diff --git a/docs/concepts/database/relations/referential-actions.html b/docs/concepts/database/relations/referential-actions.html index 6ccc967bf..05b586762 100644 --- a/docs/concepts/database/relations/referential-actions.html +++ b/docs/concepts/database/relations/referential-actions.html @@ -4,7 +4,7 @@ Referential actions | Serverpod - + diff --git a/docs/concepts/database/relations/self-relations.html b/docs/concepts/database/relations/self-relations.html index 7c0ba5a3e..4a8613604 100644 --- a/docs/concepts/database/relations/self-relations.html +++ b/docs/concepts/database/relations/self-relations.html @@ -4,7 +4,7 @@ Self-relations | Serverpod - + diff --git a/docs/concepts/database/sort.html b/docs/concepts/database/sort.html index e5a49fe91..02d2acb72 100644 --- a/docs/concepts/database/sort.html +++ b/docs/concepts/database/sort.html @@ -4,7 +4,7 @@ Sort | Serverpod - + diff --git a/docs/concepts/database/transactions.html b/docs/concepts/database/transactions.html index 4e8526619..abe06f786 100644 --- a/docs/concepts/database/transactions.html +++ b/docs/concepts/database/transactions.html @@ -4,7 +4,7 @@ Transactions | Serverpod - + diff --git a/docs/concepts/exceptions.html b/docs/concepts/exceptions.html index ebc4f6350..79b5a7438 100644 --- a/docs/concepts/exceptions.html +++ b/docs/concepts/exceptions.html @@ -4,7 +4,7 @@ Error handling and exceptions | Serverpod - + diff --git a/docs/concepts/file-uploads.html b/docs/concepts/file-uploads.html index 7404994ad..c520ad04a 100644 --- a/docs/concepts/file-uploads.html +++ b/docs/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/concepts/health-checks.html b/docs/concepts/health-checks.html index 6749e83fe..4e78cfef6 100644 --- a/docs/concepts/health-checks.html +++ b/docs/concepts/health-checks.html @@ -4,7 +4,7 @@ Health checks | Serverpod - + diff --git a/docs/concepts/logging.html b/docs/concepts/logging.html index 537500c76..3e03f8d1d 100644 --- a/docs/concepts/logging.html +++ b/docs/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/concepts/models.html b/docs/concepts/models.html index e43dc20ba..a4e45959b 100644 --- a/docs/concepts/models.html +++ b/docs/concepts/models.html @@ -4,7 +4,7 @@ Working with models | Serverpod - + @@ -31,7 +31,7 @@

EnumBy default the serialization will convert the enum to an int representing the index of the value. Changing the order may therefore have unforeseen consequences when reusing old data (such as from a database). Changing the serialization to be based on the name instead of index is easy.

enum: Animal
serialized: byName
values:
- dog
- cat
- bird

serialized has two valid values byName and byIndex. When using byName the string literal of the enum is used, when using byIndex the index value (0, 1, 2, etc) is used.

-
info

It's recommended to always set serialized to byName in any new Enum models, as this is less fragile and will be changed to the default setting in version 2 of Serverpod.

+
info

It's recommended to always set serialized to byName in any new Enum models, as this is less fragile and will be changed to the default setting in version 3 of Serverpod.

Adding documentation

Serverpod allows you to add documentation to your serializable objects in a similar way that you would add documentation to your Dart code. Use three hashes (###) to indicate that a comment should be considered documentation.

### Information about a company.
class: Company
fields:
### The name of the company.
name: String

### The date the company was founded, if known.
foundedDate: DateTime?

### A list of people currently employed at the company.
employees: List<Employee>
diff --git a/docs/concepts/modules.html b/docs/concepts/modules.html index a6e586703..45ccb263e 100644 --- a/docs/concepts/modules.html +++ b/docs/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/concepts/scheduling.html b/docs/concepts/scheduling.html index 2398f4b4a..8c20248f2 100644 --- a/docs/concepts/scheduling.html +++ b/docs/concepts/scheduling.html @@ -4,7 +4,7 @@ Scheduling | Serverpod - + diff --git a/docs/concepts/serialization.html b/docs/concepts/serialization.html index 76794871a..691809550 100644 --- a/docs/concepts/serialization.html +++ b/docs/concepts/serialization.html @@ -4,7 +4,7 @@ Custom serialization | Serverpod - + diff --git a/docs/concepts/sessions.html b/docs/concepts/sessions.html index 6e08b3bd9..aa62ab91e 100644 --- a/docs/concepts/sessions.html +++ b/docs/concepts/sessions.html @@ -4,7 +4,7 @@ Sessions | Serverpod - + diff --git a/docs/concepts/streams.html b/docs/concepts/streams.html index 75c660ca1..6270e8349 100644 --- a/docs/concepts/streams.html +++ b/docs/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/concepts/webserver.html b/docs/concepts/webserver.html index 46c3c42f3..e1872bf13 100644 --- a/docs/concepts/webserver.html +++ b/docs/concepts/webserver.html @@ -4,7 +4,7 @@ Web server | Serverpod - + diff --git a/docs/concepts/working-with-endpoints.html b/docs/concepts/working-with-endpoints.html index 9b689bd03..f137cea2c 100644 --- a/docs/concepts/working-with-endpoints.html +++ b/docs/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/contribute.html b/docs/contribute.html index 60c6d763c..858c4947f 100644 --- a/docs/contribute.html +++ b/docs/contribute.html @@ -4,7 +4,7 @@ Roadmap & contributions | Serverpod - + diff --git a/docs/deployments/deploying-to-aws.html b/docs/deployments/deploying-to-aws.html index c611cd8b8..b5bec7d66 100644 --- a/docs/deployments/deploying-to-aws.html +++ b/docs/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ AWS EC2 with Terraform | Serverpod - + diff --git a/docs/deployments/deploying-to-gce-terraform.html b/docs/deployments/deploying-to-gce-terraform.html index 74047826d..dea10d692 100644 --- a/docs/deployments/deploying-to-gce-terraform.html +++ b/docs/deployments/deploying-to-gce-terraform.html @@ -4,7 +4,7 @@ Google Cloud Engine with Terraform | Serverpod - + diff --git a/docs/deployments/deploying-to-gcr-console.html b/docs/deployments/deploying-to-gcr-console.html index 5dfa0ccad..e75f0fd66 100644 --- a/docs/deployments/deploying-to-gcr-console.html +++ b/docs/deployments/deploying-to-gcr-console.html @@ -4,7 +4,7 @@ Google Cloud Run with CGP Console | Serverpod - + diff --git a/docs/deployments/deployment-strategy.html b/docs/deployments/deployment-strategy.html index 1374c1f27..0b0710a9a 100644 --- a/docs/deployments/deployment-strategy.html +++ b/docs/deployments/deployment-strategy.html @@ -4,7 +4,7 @@ Choosing deployment strategy | Serverpod - + diff --git a/docs/deployments/general.html b/docs/deployments/general.html index 5f0324363..331178cb7 100644 --- a/docs/deployments/general.html +++ b/docs/deployments/general.html @@ -4,7 +4,7 @@ Hosting elsewhere | Serverpod - + diff --git a/docs/get-started-with-mini.html b/docs/get-started-with-mini.html index 7aa4ef728..15c752b67 100644 --- a/docs/get-started-with-mini.html +++ b/docs/get-started-with-mini.html @@ -4,7 +4,7 @@ Get started with Mini | Serverpod - + diff --git a/docs/get-started.html b/docs/get-started.html index 56c41c6b8..6139b4fff 100644 --- a/docs/get-started.html +++ b/docs/get-started.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/index.html b/docs/index.html index ef5e740fa..610a784aa 100644 --- a/docs/index.html +++ b/docs/index.html @@ -4,7 +4,7 @@ Installing Serverpod | Serverpod - + diff --git a/docs/next.html b/docs/next.html index 7f015ec74..333a3099c 100644 --- a/docs/next.html +++ b/docs/next.html @@ -4,7 +4,7 @@ Installing Serverpod | Serverpod - + diff --git a/docs/next/capabilities.html b/docs/next/capabilities.html index a634cfce3..69451b71f 100644 --- a/docs/next/capabilities.html +++ b/docs/next/capabilities.html @@ -4,7 +4,7 @@ Capabilities | Serverpod - + diff --git a/docs/next/concepts/authentication/basics.html b/docs/next/concepts/authentication/basics.html index 8ca17df08..5f49f4977 100644 --- a/docs/next/concepts/authentication/basics.html +++ b/docs/next/concepts/authentication/basics.html @@ -4,7 +4,7 @@ The basics | Serverpod - + diff --git a/docs/next/concepts/authentication/custom-overrides.html b/docs/next/concepts/authentication/custom-overrides.html index e18cff9d1..257699397 100644 --- a/docs/next/concepts/authentication/custom-overrides.html +++ b/docs/next/concepts/authentication/custom-overrides.html @@ -4,7 +4,7 @@ Custom overrides | Serverpod - + diff --git a/docs/next/concepts/authentication/providers/apple.html b/docs/next/concepts/authentication/providers/apple.html index 9b75452e0..c5a39e3d0 100644 --- a/docs/next/concepts/authentication/providers/apple.html +++ b/docs/next/concepts/authentication/providers/apple.html @@ -4,7 +4,7 @@ Apple | Serverpod - + diff --git a/docs/next/concepts/authentication/providers/custom-providers.html b/docs/next/concepts/authentication/providers/custom-providers.html index 5312f240f..88b6c0656 100644 --- a/docs/next/concepts/authentication/providers/custom-providers.html +++ b/docs/next/concepts/authentication/providers/custom-providers.html @@ -4,7 +4,7 @@ Custom providers | Serverpod - + diff --git a/docs/next/concepts/authentication/providers/email.html b/docs/next/concepts/authentication/providers/email.html index 148a85610..49717215b 100644 --- a/docs/next/concepts/authentication/providers/email.html +++ b/docs/next/concepts/authentication/providers/email.html @@ -4,7 +4,7 @@ Email | Serverpod - + diff --git a/docs/next/concepts/authentication/providers/firebase.html b/docs/next/concepts/authentication/providers/firebase.html index 1038c7fea..ade35e2bb 100644 --- a/docs/next/concepts/authentication/providers/firebase.html +++ b/docs/next/concepts/authentication/providers/firebase.html @@ -4,7 +4,7 @@ Firebase | Serverpod - + diff --git a/docs/next/concepts/authentication/providers/google.html b/docs/next/concepts/authentication/providers/google.html index d5dd27d94..1e9647915 100644 --- a/docs/next/concepts/authentication/providers/google.html +++ b/docs/next/concepts/authentication/providers/google.html @@ -4,7 +4,7 @@ Google | Serverpod - + diff --git a/docs/next/concepts/authentication/setup.html b/docs/next/concepts/authentication/setup.html index 54359e01f..0e052eeb9 100644 --- a/docs/next/concepts/authentication/setup.html +++ b/docs/next/concepts/authentication/setup.html @@ -4,7 +4,7 @@ Setup | Serverpod - + diff --git a/docs/next/concepts/authentication/working-with-users.html b/docs/next/concepts/authentication/working-with-users.html index c253bff6a..4995055d6 100644 --- a/docs/next/concepts/authentication/working-with-users.html +++ b/docs/next/concepts/authentication/working-with-users.html @@ -4,7 +4,7 @@ Working with users | Serverpod - + diff --git a/docs/next/concepts/backward-compatibility.html b/docs/next/concepts/backward-compatibility.html index 5de8e6d53..99a5c54e4 100644 --- a/docs/next/concepts/backward-compatibility.html +++ b/docs/next/concepts/backward-compatibility.html @@ -4,7 +4,7 @@ Backward compatibility | Serverpod - + diff --git a/docs/next/concepts/caching.html b/docs/next/concepts/caching.html index d206e3945..3774e0357 100644 --- a/docs/next/concepts/caching.html +++ b/docs/next/concepts/caching.html @@ -4,7 +4,7 @@ Caching | Serverpod - + diff --git a/docs/next/concepts/configuration.html b/docs/next/concepts/configuration.html index 897a76142..e4a1b1a7f 100644 --- a/docs/next/concepts/configuration.html +++ b/docs/next/concepts/configuration.html @@ -4,7 +4,7 @@ Configurations | Serverpod - + diff --git a/docs/next/concepts/database/connection.html b/docs/next/concepts/database/connection.html index 50ab14278..979a4ea72 100644 --- a/docs/next/concepts/database/connection.html +++ b/docs/next/concepts/database/connection.html @@ -4,7 +4,7 @@ Connection | Serverpod - + diff --git a/docs/next/concepts/database/crud.html b/docs/next/concepts/database/crud.html index 1320a5c7d..d52a63895 100644 --- a/docs/next/concepts/database/crud.html +++ b/docs/next/concepts/database/crud.html @@ -4,7 +4,7 @@ CRUD | Serverpod - + diff --git a/docs/next/concepts/database/filter.html b/docs/next/concepts/database/filter.html index 2b0b3a68b..9c9da3fc7 100644 --- a/docs/next/concepts/database/filter.html +++ b/docs/next/concepts/database/filter.html @@ -4,7 +4,7 @@ Filter | Serverpod - + diff --git a/docs/next/concepts/database/indexing.html b/docs/next/concepts/database/indexing.html index 09ff6620e..973e2b9d5 100644 --- a/docs/next/concepts/database/indexing.html +++ b/docs/next/concepts/database/indexing.html @@ -4,7 +4,7 @@ Indexing | Serverpod - + diff --git a/docs/next/concepts/database/migrations.html b/docs/next/concepts/database/migrations.html index a824e58a8..36b28af90 100644 --- a/docs/next/concepts/database/migrations.html +++ b/docs/next/concepts/database/migrations.html @@ -4,7 +4,7 @@ Migrations | Serverpod - + diff --git a/docs/next/concepts/database/models.html b/docs/next/concepts/database/models.html index 00eb517fd..c5508ff06 100644 --- a/docs/next/concepts/database/models.html +++ b/docs/next/concepts/database/models.html @@ -4,7 +4,7 @@ Models | Serverpod - + diff --git a/docs/next/concepts/database/pagination.html b/docs/next/concepts/database/pagination.html index bef975ee3..49542cd19 100644 --- a/docs/next/concepts/database/pagination.html +++ b/docs/next/concepts/database/pagination.html @@ -4,7 +4,7 @@ Pagination | Serverpod - + diff --git a/docs/next/concepts/database/raw-access.html b/docs/next/concepts/database/raw-access.html index bc976f4f8..01667ae00 100644 --- a/docs/next/concepts/database/raw-access.html +++ b/docs/next/concepts/database/raw-access.html @@ -4,7 +4,7 @@ Raw access | Serverpod - + diff --git a/docs/next/concepts/database/relation-queries.html b/docs/next/concepts/database/relation-queries.html index fbbd668b5..0846d444a 100644 --- a/docs/next/concepts/database/relation-queries.html +++ b/docs/next/concepts/database/relation-queries.html @@ -4,7 +4,7 @@ Relation queries | Serverpod - + diff --git a/docs/next/concepts/database/relations/many-to-many.html b/docs/next/concepts/database/relations/many-to-many.html index b050554af..f5f63e2a5 100644 --- a/docs/next/concepts/database/relations/many-to-many.html +++ b/docs/next/concepts/database/relations/many-to-many.html @@ -4,7 +4,7 @@ Many-to-many | Serverpod - + diff --git a/docs/next/concepts/database/relations/modules.html b/docs/next/concepts/database/relations/modules.html index aa5a5df4d..c081c8e99 100644 --- a/docs/next/concepts/database/relations/modules.html +++ b/docs/next/concepts/database/relations/modules.html @@ -4,7 +4,7 @@ Relations with modules | Serverpod - + diff --git a/docs/next/concepts/database/relations/one-to-many.html b/docs/next/concepts/database/relations/one-to-many.html index 0ba571d1a..e20e74944 100644 --- a/docs/next/concepts/database/relations/one-to-many.html +++ b/docs/next/concepts/database/relations/one-to-many.html @@ -4,7 +4,7 @@ One-to-many | Serverpod - + diff --git a/docs/next/concepts/database/relations/one-to-one.html b/docs/next/concepts/database/relations/one-to-one.html index 53fb3c025..ffbc826d4 100644 --- a/docs/next/concepts/database/relations/one-to-one.html +++ b/docs/next/concepts/database/relations/one-to-one.html @@ -4,7 +4,7 @@ One-to-one | Serverpod - + diff --git a/docs/next/concepts/database/relations/referential-actions.html b/docs/next/concepts/database/relations/referential-actions.html index 36775e9b4..370afef91 100644 --- a/docs/next/concepts/database/relations/referential-actions.html +++ b/docs/next/concepts/database/relations/referential-actions.html @@ -4,7 +4,7 @@ Referential actions | Serverpod - + diff --git a/docs/next/concepts/database/relations/self-relations.html b/docs/next/concepts/database/relations/self-relations.html index e96d3a824..16133c95a 100644 --- a/docs/next/concepts/database/relations/self-relations.html +++ b/docs/next/concepts/database/relations/self-relations.html @@ -4,7 +4,7 @@ Self-relations | Serverpod - + diff --git a/docs/next/concepts/database/sort.html b/docs/next/concepts/database/sort.html index ce904bbf2..efbdfdfb5 100644 --- a/docs/next/concepts/database/sort.html +++ b/docs/next/concepts/database/sort.html @@ -4,7 +4,7 @@ Sort | Serverpod - + diff --git a/docs/next/concepts/database/transactions.html b/docs/next/concepts/database/transactions.html index 42701d546..6b1b327bd 100644 --- a/docs/next/concepts/database/transactions.html +++ b/docs/next/concepts/database/transactions.html @@ -4,7 +4,7 @@ Transactions | Serverpod - + diff --git a/docs/next/concepts/exceptions.html b/docs/next/concepts/exceptions.html index c5947723e..a9dd1be9e 100644 --- a/docs/next/concepts/exceptions.html +++ b/docs/next/concepts/exceptions.html @@ -4,7 +4,7 @@ Error handling and exceptions | Serverpod - + diff --git a/docs/next/concepts/experimental.html b/docs/next/concepts/experimental.html index 653736512..1d9c86c40 100644 --- a/docs/next/concepts/experimental.html +++ b/docs/next/concepts/experimental.html @@ -4,7 +4,7 @@ Experimental features | Serverpod - + diff --git a/docs/next/concepts/file-uploads.html b/docs/next/concepts/file-uploads.html index 626d7444c..681f982bb 100644 --- a/docs/next/concepts/file-uploads.html +++ b/docs/next/concepts/file-uploads.html @@ -4,7 +4,7 @@ Uploading files | Serverpod - + diff --git a/docs/next/concepts/health-checks.html b/docs/next/concepts/health-checks.html index c05db5f33..b13def308 100644 --- a/docs/next/concepts/health-checks.html +++ b/docs/next/concepts/health-checks.html @@ -4,7 +4,7 @@ Health checks | Serverpod - + diff --git a/docs/next/concepts/logging.html b/docs/next/concepts/logging.html index 57f97ff0a..347347a92 100644 --- a/docs/next/concepts/logging.html +++ b/docs/next/concepts/logging.html @@ -4,7 +4,7 @@ Logging | Serverpod - + diff --git a/docs/next/concepts/models.html b/docs/next/concepts/models.html index e1303dbc0..87522c925 100644 --- a/docs/next/concepts/models.html +++ b/docs/next/concepts/models.html @@ -4,7 +4,7 @@ Working with models | Serverpod - + @@ -32,7 +32,7 @@

EnumBy default the serialization will convert the enum to an int representing the index of the value. Changing the order may therefore have unforeseen consequences when reusing old data (such as from a database). Changing the serialization to be based on the name instead of index is easy.

enum: Animal
serialized: byName
values:
- dog
- cat
- bird

serialized has two valid values byName and byIndex. When using byName the string literal of the enum is used, when using byIndex the index value (0, 1, 2, etc) is used.

-
info

It's recommended to always set serialized to byName in any new Enum models, as this is less fragile and will be changed to the default setting in version 2 of Serverpod.

+
info

It's recommended to always set serialized to byName in any new Enum models, as this is less fragile and will be changed to the default setting in version 3 of Serverpod.

Adding documentation

Serverpod allows you to add documentation to your serializable objects in a similar way that you would add documentation to your Dart code. Use three hashes (###) to indicate that a comment should be considered documentation.

### Information about a company.
class: Company
fields:
### The name of the company.
name: String

### The date the company was founded, if known.
foundedDate: DateTime?

### A list of people currently employed at the company.
employees: List<Employee>
diff --git a/docs/next/concepts/modules.html b/docs/next/concepts/modules.html index 0a7b7cc2c..f91c24330 100644 --- a/docs/next/concepts/modules.html +++ b/docs/next/concepts/modules.html @@ -4,7 +4,7 @@ Modules | Serverpod - + diff --git a/docs/next/concepts/scheduling.html b/docs/next/concepts/scheduling.html index 717529421..7e3317efe 100644 --- a/docs/next/concepts/scheduling.html +++ b/docs/next/concepts/scheduling.html @@ -4,7 +4,7 @@ Scheduling | Serverpod - + diff --git a/docs/next/concepts/serialization.html b/docs/next/concepts/serialization.html index 46bf1c2be..d85d64a8b 100644 --- a/docs/next/concepts/serialization.html +++ b/docs/next/concepts/serialization.html @@ -4,7 +4,7 @@ Custom serialization | Serverpod - + diff --git a/docs/next/concepts/sessions.html b/docs/next/concepts/sessions.html index e32b4f01a..935260df6 100644 --- a/docs/next/concepts/sessions.html +++ b/docs/next/concepts/sessions.html @@ -4,7 +4,7 @@ Sessions | Serverpod - + diff --git a/docs/next/concepts/streams.html b/docs/next/concepts/streams.html index aaaaadd7a..6b9727a9a 100644 --- a/docs/next/concepts/streams.html +++ b/docs/next/concepts/streams.html @@ -4,7 +4,7 @@ Streams and messaging | Serverpod - + diff --git a/docs/next/concepts/testing/advanced-examples.html b/docs/next/concepts/testing/advanced-examples.html index b1ee205b9..520744e1d 100644 --- a/docs/next/concepts/testing/advanced-examples.html +++ b/docs/next/concepts/testing/advanced-examples.html @@ -4,7 +4,7 @@ Advanced examples | Serverpod - + diff --git a/docs/next/concepts/testing/best-practises.html b/docs/next/concepts/testing/best-practises.html index 166c8e992..3d04a581c 100644 --- a/docs/next/concepts/testing/best-practises.html +++ b/docs/next/concepts/testing/best-practises.html @@ -4,7 +4,7 @@ Best practises | Serverpod - + diff --git a/docs/next/concepts/testing/get-started.html b/docs/next/concepts/testing/get-started.html index 01ffbc6da..d19d17253 100644 --- a/docs/next/concepts/testing/get-started.html +++ b/docs/next/concepts/testing/get-started.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/next/concepts/testing/the-basics.html b/docs/next/concepts/testing/the-basics.html index 783ac3dec..85e65d050 100644 --- a/docs/next/concepts/testing/the-basics.html +++ b/docs/next/concepts/testing/the-basics.html @@ -4,7 +4,7 @@ The basics | Serverpod - + diff --git a/docs/next/concepts/webserver.html b/docs/next/concepts/webserver.html index dae8f6cb7..05cba4831 100644 --- a/docs/next/concepts/webserver.html +++ b/docs/next/concepts/webserver.html @@ -4,7 +4,7 @@ Web server | Serverpod - + diff --git a/docs/next/concepts/working-with-endpoints.html b/docs/next/concepts/working-with-endpoints.html index 195b022fd..50849dc5a 100644 --- a/docs/next/concepts/working-with-endpoints.html +++ b/docs/next/concepts/working-with-endpoints.html @@ -4,7 +4,7 @@ Working with endpoints | Serverpod - + diff --git a/docs/next/contribute.html b/docs/next/contribute.html index 7c15d2a09..faa7ca305 100644 --- a/docs/next/contribute.html +++ b/docs/next/contribute.html @@ -4,7 +4,7 @@ Roadmap & contributions | Serverpod - + diff --git a/docs/next/deployments/deploying-to-aws.html b/docs/next/deployments/deploying-to-aws.html index b071b5525..fa52fa8e1 100644 --- a/docs/next/deployments/deploying-to-aws.html +++ b/docs/next/deployments/deploying-to-aws.html @@ -4,7 +4,7 @@ AWS EC2 with Terraform | Serverpod - + diff --git a/docs/next/deployments/deploying-to-gce-terraform.html b/docs/next/deployments/deploying-to-gce-terraform.html index 2dc168212..d3f9f2bb8 100644 --- a/docs/next/deployments/deploying-to-gce-terraform.html +++ b/docs/next/deployments/deploying-to-gce-terraform.html @@ -4,7 +4,7 @@ Google Cloud Engine with Terraform | Serverpod - + diff --git a/docs/next/deployments/deploying-to-gcr-console.html b/docs/next/deployments/deploying-to-gcr-console.html index 10be21968..f0d2faa45 100644 --- a/docs/next/deployments/deploying-to-gcr-console.html +++ b/docs/next/deployments/deploying-to-gcr-console.html @@ -4,7 +4,7 @@ Google Cloud Run with CGP Console | Serverpod - + diff --git a/docs/next/deployments/deployment-strategy.html b/docs/next/deployments/deployment-strategy.html index c4ae515f5..94768f3be 100644 --- a/docs/next/deployments/deployment-strategy.html +++ b/docs/next/deployments/deployment-strategy.html @@ -4,7 +4,7 @@ Choosing deployment strategy | Serverpod - + diff --git a/docs/next/deployments/general.html b/docs/next/deployments/general.html index 3ee2c40f0..d8a42463e 100644 --- a/docs/next/deployments/general.html +++ b/docs/next/deployments/general.html @@ -4,7 +4,7 @@ Hosting elsewhere | Serverpod - + diff --git a/docs/next/get-started-with-mini.html b/docs/next/get-started-with-mini.html index fb4930527..86ad76bf9 100644 --- a/docs/next/get-started-with-mini.html +++ b/docs/next/get-started-with-mini.html @@ -4,7 +4,7 @@ Get started with Mini | Serverpod - + diff --git a/docs/next/get-started.html b/docs/next/get-started.html index 28c982a89..96539c875 100644 --- a/docs/next/get-started.html +++ b/docs/next/get-started.html @@ -4,7 +4,7 @@ Get started | Serverpod - + diff --git a/docs/next/support.html b/docs/next/support.html index ea37b1eb4..cffef75ea 100644 --- a/docs/next/support.html +++ b/docs/next/support.html @@ -4,7 +4,7 @@ Support & community | Serverpod - + diff --git a/docs/next/tools/insights.html b/docs/next/tools/insights.html index 7c865639b..f0473beda 100644 --- a/docs/next/tools/insights.html +++ b/docs/next/tools/insights.html @@ -4,7 +4,7 @@ Serverpod Insights | Serverpod - + diff --git a/docs/next/tools/lsp.html b/docs/next/tools/lsp.html index 5c1555b99..b06dbf6a4 100644 --- a/docs/next/tools/lsp.html +++ b/docs/next/tools/lsp.html @@ -4,7 +4,7 @@ LSP server | Serverpod - + diff --git a/docs/next/tutorials/authentication.html b/docs/next/tutorials/authentication.html index a0201e62e..abc4cf98d 100644 --- a/docs/next/tutorials/authentication.html +++ b/docs/next/tutorials/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/next/tutorials/code-example.html b/docs/next/tutorials/code-example.html index 742c3f979..1384b4198 100644 --- a/docs/next/tutorials/code-example.html +++ b/docs/next/tutorials/code-example.html @@ -4,7 +4,7 @@ Code examples | Serverpod - + diff --git a/docs/next/tutorials/first-app.html b/docs/next/tutorials/first-app.html index 0ba4b8643..e89326bd0 100644 --- a/docs/next/tutorials/first-app.html +++ b/docs/next/tutorials/first-app.html @@ -4,7 +4,7 @@ Build your first app | Serverpod - + diff --git a/docs/next/tutorials/real-time-communication.html b/docs/next/tutorials/real-time-communication.html index eb8c4c8ab..3fd2cd5f7 100644 --- a/docs/next/tutorials/real-time-communication.html +++ b/docs/next/tutorials/real-time-communication.html @@ -4,7 +4,7 @@ Real-time communication | Serverpod - + diff --git a/docs/next/upgrading/upgrade-from-mini.html b/docs/next/upgrading/upgrade-from-mini.html index cfbb3f451..d48d39f57 100644 --- a/docs/next/upgrading/upgrade-from-mini.html +++ b/docs/next/upgrading/upgrade-from-mini.html @@ -4,7 +4,7 @@ Upgrade from Mini to full | Serverpod - + diff --git a/docs/next/upgrading/upgrade-to-one-point-two.html b/docs/next/upgrading/upgrade-to-one-point-two.html index 43872174e..3dbefbf70 100644 --- a/docs/next/upgrading/upgrade-to-one-point-two.html +++ b/docs/next/upgrading/upgrade-to-one-point-two.html @@ -4,7 +4,7 @@ Upgrade to 1.2 | Serverpod - + diff --git a/docs/next/upgrading/upgrade-to-two.html b/docs/next/upgrading/upgrade-to-two.html index db45091b1..c4c1f8d76 100644 --- a/docs/next/upgrading/upgrade-to-two.html +++ b/docs/next/upgrading/upgrade-to-two.html @@ -4,7 +4,7 @@ Upgrade to 2.0 | Serverpod - + @@ -104,7 +104,7 @@

Updat

With the release of Serverpod 2.0, the fromJson constructor has been simplified and the serializationManager has been removed:

factory ClassName.fromJson(
Map<String, dynamic> json,
) {
return ClassName(
json['name'],
);
}

Deprecation Notice for SerializableEntity

-

The SerializableEntity class is deprecated and will be removed in version 2.1. Please implement the SerializableModel interface instead for creating serializable models.

+

The SerializableEntity class is deprecated and will be removed in version 3. Please implement the SerializableModel interface instead for creating serializable models.

Migration Guide

To migrate your code from SerializableEntity to SerializableModel, replace extends SerializableEntity with implements SerializableModel in your model classes.

Example

diff --git a/docs/support.html b/docs/support.html index 8106efce5..4917d9d8e 100644 --- a/docs/support.html +++ b/docs/support.html @@ -4,7 +4,7 @@ Support & community | Serverpod - + diff --git a/docs/tools/insights.html b/docs/tools/insights.html index 335a5a692..9038cfc8c 100644 --- a/docs/tools/insights.html +++ b/docs/tools/insights.html @@ -4,7 +4,7 @@ Serverpod Insights | Serverpod - + diff --git a/docs/tools/lsp.html b/docs/tools/lsp.html index c59108287..3aae0c6b8 100644 --- a/docs/tools/lsp.html +++ b/docs/tools/lsp.html @@ -4,7 +4,7 @@ LSP server | Serverpod - + diff --git a/docs/tutorials/authentication.html b/docs/tutorials/authentication.html index efbedf1b1..0e3939f6f 100644 --- a/docs/tutorials/authentication.html +++ b/docs/tutorials/authentication.html @@ -4,7 +4,7 @@ Authentication | Serverpod - + diff --git a/docs/tutorials/code-example.html b/docs/tutorials/code-example.html index 67a54be23..686386269 100644 --- a/docs/tutorials/code-example.html +++ b/docs/tutorials/code-example.html @@ -4,7 +4,7 @@ Code examples | Serverpod - + diff --git a/docs/tutorials/first-app.html b/docs/tutorials/first-app.html index 3a81fbb9c..1f395e4e6 100644 --- a/docs/tutorials/first-app.html +++ b/docs/tutorials/first-app.html @@ -4,7 +4,7 @@ Build your first app | Serverpod - + diff --git a/docs/tutorials/real-time-communication.html b/docs/tutorials/real-time-communication.html index 86ff973d7..e7a31282a 100644 --- a/docs/tutorials/real-time-communication.html +++ b/docs/tutorials/real-time-communication.html @@ -4,7 +4,7 @@ Real-time communication | Serverpod - + diff --git a/docs/upgrading/upgrade-from-mini.html b/docs/upgrading/upgrade-from-mini.html index e6112e2de..f44e9bb8d 100644 --- a/docs/upgrading/upgrade-from-mini.html +++ b/docs/upgrading/upgrade-from-mini.html @@ -4,7 +4,7 @@ Upgrade from Mini to full | Serverpod - + diff --git a/docs/upgrading/upgrade-to-one-point-two.html b/docs/upgrading/upgrade-to-one-point-two.html index 29a518288..0a2a8b5b8 100644 --- a/docs/upgrading/upgrade-to-one-point-two.html +++ b/docs/upgrading/upgrade-to-one-point-two.html @@ -4,7 +4,7 @@ Upgrade to 1.2 | Serverpod - + diff --git a/docs/upgrading/upgrade-to-two.html b/docs/upgrading/upgrade-to-two.html index 1f6bbccab..c2f6d316c 100644 --- a/docs/upgrading/upgrade-to-two.html +++ b/docs/upgrading/upgrade-to-two.html @@ -4,7 +4,7 @@ Upgrade to 2.0 | Serverpod - + @@ -104,7 +104,7 @@

Updat

With the release of Serverpod 2.0, the fromJson constructor has been simplified and the serializationManager has been removed:

factory ClassName.fromJson(
Map<String, dynamic> json,
) {
return ClassName(
json['name'],
);
}

Deprecation Notice for SerializableEntity

-

The SerializableEntity class is deprecated and will be removed in version 2.1. Please implement the SerializableModel interface instead for creating serializable models.

+

The SerializableEntity class is deprecated and will be removed in version 3. Please implement the SerializableModel interface instead for creating serializable models.

Migration Guide

To migrate your code from SerializableEntity to SerializableModel, replace extends SerializableEntity with implements SerializableModel in your model classes.

Example