From ad8b17c824bfd6dcbe2725f8cb9cc509431c71b9 Mon Sep 17 00:00:00 2001 From: Michael Bryzek Date: Thu, 11 Jul 2024 11:56:59 -0400 Subject: [PATCH] Upgrade to play 2.9 / scala 3 (#937) --- .apibuilder/.tracked_files | 20 +- .apibuilder/config | 13 +- .github/workflows/ci.yml | 2 +- .scalafmt.conf | 9 + .travis.yml | 23 - README.md | 2 +- TODO | 2 +- .../controllers/ApiBuilderController.scala | 8 +- api/app/controllers/Attributes.scala | 8 +- api/app/controllers/Authentications.scala | 2 +- .../BatchDownloadApplications.scala | 6 +- api/app/controllers/Changes.scala | 2 +- api/app/controllers/Code.scala | 4 +- api/app/controllers/Domains.scala | 4 +- api/app/controllers/GeneratorServices.scala | 8 +- api/app/controllers/Items.scala | 4 +- api/app/controllers/MembershipRequests.scala | 3 +- .../controllers/PasswordResetRequests.scala | 2 +- api/app/controllers/PasswordResets.scala | 2 +- api/app/controllers/Subscriptions.scala | 9 +- api/app/controllers/Users.scala | 29 +- api/app/db/ItemsDao.scala | 2 +- api/app/db/OrganizationsDao.scala | 2 +- api/app/db/TokensDao.scala | 2 +- api/app/db/UserPasswordsDao.scala | 110 +- api/app/db/VersionsDao.scala | 2 +- api/app/db/WatchesDao.scala | 2 +- .../GeneratorApibuilderSessionsDao.scala | 24 +- ...sqlApibuilderGeneratorInvocationsDao.scala | 8 +- .../db/generated/PsqlApibuilderTasksDao.scala | 4 +- ...collectiveApibuilderApiV0Conversions.scala | 145 +- ...lectiveApibuilderCommonV0Conversions.scala | 39 +- ...tiveApibuilderGeneratorV0Conversions.scala | 45 +- ...ollectiveApibuilderSpecV0Conversions.scala | 85 +- api/app/lib/AppConfig.scala | 18 +- api/app/lib/Config.scala | 12 + api/app/lib/EmailUtil.scala | 8 +- api/app/lib/ExampleJson.scala | 2 +- api/app/lib/ServiceDiff.scala | 4 +- api/app/logger/ApiBuilderLogger.scala | 172 ++ api/app/processor/PurgeDeletedProcessor.scala | 6 +- .../ApiBuilderServiceImportResolver.scala | 10 +- api/conf/application.production.conf | 2 + api/conf/base.conf | 1 - .../controllers/ApplicationMetadataSpec.scala | 2 +- api/test/db/MembershipRequestsDaoSpec.scala | 2 +- api/test/db/UserPasswordsDaoSpec.scala | 16 +- api/test/db/VersionsDaoSpec.scala | 4 +- .../lib/OriginalGeneratorHelpersSpec.scala | 2 +- app/app/controllers/AccountController.scala | 6 +- .../AccountProfileController.scala | 17 +- .../controllers/ApplicationController.scala | 7 +- app/app/controllers/ApplicationSettings.scala | 26 +- .../controllers/AttributesController.scala | 20 +- app/app/controllers/Domains.scala | 19 +- app/app/controllers/EmailVerifications.scala | 3 +- app/app/controllers/GeneratorServices.scala | 5 +- app/app/controllers/Generators.scala | 18 +- app/app/controllers/GithubController.scala | 12 +- app/app/controllers/Healthchecks.scala | 3 +- app/app/controllers/HistoryController.scala | 3 +- app/app/controllers/LoginController.scala | 50 +- app/app/controllers/LogoutController.scala | 6 +- app/app/controllers/Members.scala | 28 +- .../MembershipRequestReviews.scala | 6 +- .../OrganizationAttributesController.scala | 17 +- app/app/controllers/Organizations.scala | 5 + app/app/controllers/SearchController.scala | 3 +- app/app/controllers/Subscriptions.scala | 7 +- app/app/controllers/TokensController.scala | 22 +- app/app/controllers/Versions.scala | 38 +- app/app/lib/MemberDownload.scala | 9 +- app/app/views/attributes/create.scala.html | 2 +- app/app/views/doc/releaseNotes.scala.html | 26 + app/app/views/doc/start.scala.html | 2 +- app/app/views/generators/create.scala.html | 2 +- app/app/views/index.scala.html | 2 +- app/app/views/login/legacy.scala.html | 4 +- app/app/views/main.scala.html | 4 +- app/app/views/tokens/index.scala.html | 4 +- app/app/views/versions/form.scala.html | 16 +- app/app/views/versions/show.scala.html | 14 +- app/app/views/versions/values.scala.html | 15 +- app/conf/routes | 8 +- .../scala/io/apibuilder/avro/ParserSpec.scala | 6 +- build.sbt | 92 +- .../core => app}/DuplicateJsonParser.scala | 0 .../main/scala/core => app}/Importer.scala | 0 .../scala/core => app}/ServiceFetcher.scala | 0 .../scala/core => app}/TypeValidator.scala | 14 +- core/{src/main/scala/core => app}/Util.scala | 0 .../scala/core => app}/VersionMigration.scala | 0 .../builder/DuplicateErrorMessage.scala | 0 .../scala/core => app}/builder/JsonUtil.scala | 0 .../builder/OriginalValidator.scala | 0 .../builder/ServiceSpecValidator.scala | 28 +- .../api_json/ApiJsonServiceValidator.scala | 4 +- .../api_json/InternalApiJsonForm.scala | 2 +- .../builder/api_json/InternalDatatype.scala | 0 .../builder/api_json/ServiceBuilder.scala | 12 +- .../ServiceJsonServiceValidator.scala | 0 .../core => app}/builder/api_json/Types.scala | 10 +- .../api_json/templates/ArrayMerge.scala | 0 .../api_json/templates/AttributeMerge.scala | 0 .../api_json/templates/HeaderMerge.scala | 0 .../builder/api_json/templates/JsMerge.scala | 0 .../builder/api_json/templates/MapMerge.scala | 0 .../api_json/templates/ModelMerge.scala | 0 .../api_json/templates/OptionHelpers.scala | 0 .../api_json/templates/RenameTypes.scala | 0 .../api_json/templates/ResourceMerge.scala | 0 .../api_json/templates/TemplateMerge.scala | 2 +- .../InterfacesToSupportResources.scala | 0 .../upgrades/RemoveApiDocElement.scala | 0 .../api_json/upgrades/ServiceParser.scala | 0 .../builder/api_json/upgrades/Upgrader.scala | 0 ...icollectiveApibuilderApiJsonV0Models.scala | 4 +- .../core/ApiJsonStructureSpec.scala | 0 .../core/BodyParameterSpec.scala | 0 .../test/scala => test}/core/BrokenSpec.scala | 0 .../scala => test}/core/DeprecationSpec.scala | 0 .../core/DuplicateFieldValidatorSpec.scala | 0 .../core/DuplicateNamesSpec.scala | 0 .../test/scala => test}/core/EnumSpec.scala | 0 .../core/FileServiceFetcher.scala | 0 .../core/ImportServiceApiJsonSpec.scala | 0 .../core/ImportServiceServiceJsonSpec.scala | 0 .../core/ImportedResourcePathsSpec.scala | 0 .../scala => test}/core/ImporterSpec.scala | 0 .../test/scala => test}/core/InfoSpec.scala | 0 .../core/InlineEnumInModelFieldsSpec.scala | 0 .../scala => test}/core/InlineEnumsSpec.scala | 0 .../core/InlineModelsSpec.scala | 0 .../core/InlineUnionsSpec.scala | 4 +- .../core/InterfaceImportsSpec.scala | 0 .../scala => test}/core/InterfaceSpec.scala | 0 .../core/MockServiceFetcher.scala | 0 .../core/NestedUnionsSpec.scala | 66 +- .../core/OriginalValidatorSpec.scala | 4 +- .../core/ServiceAnnotationsSpec.scala | 0 .../core/ServiceCommonReturnTypeSpec.scala | 0 .../core/ServiceDefaultsSpec.scala | 0 .../scala => test}/core/ServiceEnumSpec.scala | 0 .../core/ServiceHeaderImportsSpec.scala | 0 .../core/ServiceHeadersSpec.scala | 0 .../core/ServiceInternalReferencesSpec.scala | 0 .../scala => test}/core/ServiceMapSpec.scala | 0 .../core/ServiceMethodsSpec.scala | 0 .../core/ServiceParametersSpec.scala | 0 .../core/ServicePathParametersSpec.scala | 0 .../core/ServiceResourcesSpec.scala | 0 .../core/ServiceResponsesSpec.scala | 0 .../core/ServiceValidatorSpec.scala | 2 +- .../core/SvcApiDocJsonSpec.scala | 0 .../scala => test}/core/SvcIrisHubSpec.scala | 2 +- .../scala => test}/core/TemplateSpec.scala | 0 .../test/scala => test}/core/TestHelper.scala | 4 +- .../core/TypeValidatorSpec.scala | 0 .../core/UnionTypeDefaultSpec.scala | 0 .../UnionTypeDiscriminatorValueSpec.scala | 0 .../scala => test}/core/UnionTypeSpec.scala | 2 +- .../test/scala => test}/core/UtilSpec.scala | 0 .../core/builder/JsonUtilSpec.scala | 0 .../api_json/InternalDatatypeSpec.scala | 0 .../api_json/templates/ModelMergeSpec.scala | 2 +- .../templates/ResourceMergeSpec.scala | 0 .../upgrades/RemoveApiDocElementSpec.scala | 0 .../api_json/upgrades/ServiceParserSpec.scala | 0 .../helpers/ApiJsonHelpers.scala | 0 .../helpers/RandomHelpers.scala | 0 .../helpers/ServiceHelpers.scala | 0 .../helpers/ValidatedTestHelpers.scala | 4 +- .../test/resources/apibuilder-service.json | 0 .../test/resources/apidoc/plugin.properties | 0 .../test/resources/avro/circular.avsc | 0 .../test/resources/avro/circular.json | 0 .../test/resources/avro/example.avsc | 0 .../test/resources/avro/example.json | 0 ...json-spec-readers-quality-plan-writers.txt | 0 .../test/resources/simple-w-array.json | 0 .../test/resources/simple-without-array.json | 0 .../test/resources/svc-iris-hub-0-0-1.json | 0 dao/spec/psql-apibuilder.json | 4 + .../ApicollectiveApibuilderApiV0Client.scala | 77 +- ...picollectiveApibuilderCommonV0Client.scala | 28 +- ...llectiveApibuilderCommonV0MockClient.scala | 4 +- ...ollectiveApibuilderGeneratorV0Client.scala | 28 +- ...ctiveApibuilderGeneratorV0MockClient.scala | 4 +- .../ApicollectiveApibuilderSpecV0Client.scala | 58 +- ...collectiveApibuilderSpecV0MockClient.scala | 4 +- .../ApicollectiveApibuilderTaskV0Client.scala | 199 ++- ...collectiveApibuilderTaskV0MockClient.scala | 4 +- lib/src/main/scala/Kind.scala | 2 +- .../ApicollectiveApibuilderSpecV0Models.scala | 1416 +++++++++++++++++ .../scala/helpers/ValidatedTestHelpers.scala | 10 +- project/plugins.sbt | 4 +- spec/apibuilder-task.json | 1 + .../scala/io/apibuilder/swagger/Parser.scala | 2 +- .../scala/io/apibuilder/swagger/Util.scala | 2 +- .../swagger/translators/Field.scala | 2 +- .../swagger/translators/Model.scala | 14 +- .../swagger/translators/Operation.scala | 2 +- .../swagger/SwaggerServiceValidatorSpec.scala | 2 +- 203 files changed, 2453 insertions(+), 1000 deletions(-) create mode 100644 .scalafmt.conf delete mode 100644 .travis.yml create mode 100644 api/app/logger/ApiBuilderLogger.scala rename core/{src/main/scala/core => app}/DuplicateJsonParser.scala (100%) rename core/{src/main/scala/core => app}/Importer.scala (100%) rename core/{src/main/scala/core => app}/ServiceFetcher.scala (100%) rename core/{src/main/scala/core => app}/TypeValidator.scala (97%) rename core/{src/main/scala/core => app}/Util.scala (100%) rename core/{src/main/scala/core => app}/VersionMigration.scala (100%) rename core/{src/main/scala/core => app}/builder/DuplicateErrorMessage.scala (100%) rename core/{src/main/scala/core => app}/builder/JsonUtil.scala (100%) rename core/{src/main/scala/core => app}/builder/OriginalValidator.scala (100%) rename core/{src/main/scala/core => app}/builder/ServiceSpecValidator.scala (97%) rename core/{src/main/scala/core => app}/builder/api_json/ApiJsonServiceValidator.scala (99%) rename core/{src/main/scala/core => app}/builder/api_json/InternalApiJsonForm.scala (99%) rename core/{src/main/scala/core => app}/builder/api_json/InternalDatatype.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/ServiceBuilder.scala (98%) rename core/{src/main/scala/core => app}/builder/api_json/ServiceJsonServiceValidator.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/Types.scala (96%) rename core/{src/main/scala/core => app}/builder/api_json/templates/ArrayMerge.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/templates/AttributeMerge.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/templates/HeaderMerge.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/templates/JsMerge.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/templates/MapMerge.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/templates/ModelMerge.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/templates/OptionHelpers.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/templates/RenameTypes.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/templates/ResourceMerge.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/templates/TemplateMerge.scala (97%) rename core/{src/main/scala/core => app}/builder/api_json/upgrades/InterfacesToSupportResources.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/upgrades/RemoveApiDocElement.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/upgrades/ServiceParser.scala (100%) rename core/{src/main/scala/core => app}/builder/api_json/upgrades/Upgrader.scala (100%) rename core/{src/main/scala/core => app}/generated/ApicollectiveApibuilderApiJsonV0Models.scala (99%) rename core/{src/test/scala => test}/core/ApiJsonStructureSpec.scala (100%) rename core/{src/test/scala => test}/core/BodyParameterSpec.scala (100%) rename core/{src/test/scala => test}/core/BrokenSpec.scala (100%) rename core/{src/test/scala => test}/core/DeprecationSpec.scala (100%) rename core/{src/test/scala => test}/core/DuplicateFieldValidatorSpec.scala (100%) rename core/{src/test/scala => test}/core/DuplicateNamesSpec.scala (100%) rename core/{src/test/scala => test}/core/EnumSpec.scala (100%) rename core/{src/test/scala => test}/core/FileServiceFetcher.scala (100%) rename core/{src/test/scala => test}/core/ImportServiceApiJsonSpec.scala (100%) rename core/{src/test/scala => test}/core/ImportServiceServiceJsonSpec.scala (100%) rename core/{src/test/scala => test}/core/ImportedResourcePathsSpec.scala (100%) rename core/{src/test/scala => test}/core/ImporterSpec.scala (100%) rename core/{src/test/scala => test}/core/InfoSpec.scala (100%) rename core/{src/test/scala => test}/core/InlineEnumInModelFieldsSpec.scala (100%) rename core/{src/test/scala => test}/core/InlineEnumsSpec.scala (100%) rename core/{src/test/scala => test}/core/InlineModelsSpec.scala (100%) rename core/{src/test/scala => test}/core/InlineUnionsSpec.scala (99%) rename core/{src/test/scala => test}/core/InterfaceImportsSpec.scala (100%) rename core/{src/test/scala => test}/core/InterfaceSpec.scala (100%) rename core/{src/test/scala => test}/core/MockServiceFetcher.scala (100%) rename core/{src/test/scala => test}/core/NestedUnionsSpec.scala (60%) rename core/{src/test/scala => test}/core/OriginalValidatorSpec.scala (92%) rename core/{src/test/scala => test}/core/ServiceAnnotationsSpec.scala (100%) rename core/{src/test/scala => test}/core/ServiceCommonReturnTypeSpec.scala (100%) rename core/{src/test/scala => test}/core/ServiceDefaultsSpec.scala (100%) rename core/{src/test/scala => test}/core/ServiceEnumSpec.scala (100%) rename core/{src/test/scala => test}/core/ServiceHeaderImportsSpec.scala (100%) rename core/{src/test/scala => test}/core/ServiceHeadersSpec.scala (100%) rename core/{src/test/scala => test}/core/ServiceInternalReferencesSpec.scala (100%) rename core/{src/test/scala => test}/core/ServiceMapSpec.scala (100%) rename core/{src/test/scala => test}/core/ServiceMethodsSpec.scala (100%) rename core/{src/test/scala => test}/core/ServiceParametersSpec.scala (100%) rename core/{src/test/scala => test}/core/ServicePathParametersSpec.scala (100%) rename core/{src/test/scala => test}/core/ServiceResourcesSpec.scala (100%) rename core/{src/test/scala => test}/core/ServiceResponsesSpec.scala (100%) rename core/{src/test/scala => test}/core/ServiceValidatorSpec.scala (99%) rename core/{src/test/scala => test}/core/SvcApiDocJsonSpec.scala (100%) rename core/{src/test/scala => test}/core/SvcIrisHubSpec.scala (98%) rename core/{src/test/scala => test}/core/TemplateSpec.scala (100%) rename core/{src/test/scala => test}/core/TestHelper.scala (98%) rename core/{src/test/scala => test}/core/TypeValidatorSpec.scala (100%) rename core/{src/test/scala => test}/core/UnionTypeDefaultSpec.scala (100%) rename core/{src/test/scala => test}/core/UnionTypeDiscriminatorValueSpec.scala (100%) rename core/{src/test/scala => test}/core/UnionTypeSpec.scala (99%) rename core/{src/test/scala => test}/core/UtilSpec.scala (100%) rename core/{src/test/scala => test}/core/builder/JsonUtilSpec.scala (100%) rename core/{src/test/scala => test}/core/builder/api_json/InternalDatatypeSpec.scala (100%) rename core/{src/test/scala => test}/core/builder/api_json/templates/ModelMergeSpec.scala (99%) rename core/{src/test/scala => test}/core/builder/api_json/templates/ResourceMergeSpec.scala (100%) rename core/{src/test/scala => test}/core/builder/api_json/upgrades/RemoveApiDocElementSpec.scala (100%) rename core/{src/test/scala => test}/core/builder/api_json/upgrades/ServiceParserSpec.scala (100%) rename core/{src/test/scala => test}/helpers/ApiJsonHelpers.scala (100%) rename core/{src/test/scala => test}/helpers/RandomHelpers.scala (100%) rename core/{src/test/scala => test}/helpers/ServiceHelpers.scala (100%) rename core/{src/test/scala => test}/helpers/ValidatedTestHelpers.scala (78%) rename core/{src => }/test/resources/apibuilder-service.json (100%) rename core/{src => }/test/resources/apidoc/plugin.properties (100%) rename core/{src => }/test/resources/avro/circular.avsc (100%) rename core/{src => }/test/resources/avro/circular.json (100%) rename core/{src => }/test/resources/avro/example.avsc (100%) rename core/{src => }/test/resources/avro/example.json (100%) rename core/{src => }/test/resources/generators/play-2-json-spec-readers-quality-plan-writers.txt (100%) rename core/{src => }/test/resources/simple-w-array.json (100%) rename core/{src => }/test/resources/simple-without-array.json (100%) rename core/{src => }/test/resources/svc-iris-hub-0-0-1.json (100%) create mode 100644 lib/src/main/scala/generated/ApicollectiveApibuilderSpecV0Models.scala diff --git a/.apibuilder/.tracked_files b/.apibuilder/.tracked_files index 1d8610353..6452dd836 100644 --- a/.apibuilder/.tracked_files +++ b/.apibuilder/.tracked_files @@ -4,39 +4,39 @@ apicollective: anorm_2_8_parsers: - api/app/generated/ApicollectiveApibuilderApiV0Conversions.scala - api/app/generated/ApicollectiveApibuilderApiV0Parsers.scala - play_2_8_client: + play_2_9_scala_3_client: - generated/app/ApicollectiveApibuilderApiV0Client.scala play_2_x_routes: - api/conf/routes apibuilder-api-json: - play_2_x_json: + play_2_x_scala_3_json: - core/src/main/scala/core/generated/ApicollectiveApibuilderApiJsonV0Models.scala apibuilder-common: anorm_2_8_parsers: - api/app/generated/ApicollectiveApibuilderCommonV0Conversions.scala - api/app/generated/ApicollectiveApibuilderCommonV0Parsers.scala - play_2_8_client: - - generated/app/ApicollectiveApibuilderCommonV0Client.scala play_2_8_mock_client: - generated/app/ApicollectiveApibuilderCommonV0MockClient.scala + play_2_9_scala_3_client: + - generated/app/ApicollectiveApibuilderCommonV0Client.scala apibuilder-generator: anorm_2_8_parsers: - api/app/generated/ApicollectiveApibuilderGeneratorV0Conversions.scala - api/app/generated/ApicollectiveApibuilderGeneratorV0Parsers.scala - play_2_8_client: - - generated/app/ApicollectiveApibuilderGeneratorV0Client.scala play_2_8_mock_client: - generated/app/ApicollectiveApibuilderGeneratorV0MockClient.scala + play_2_9_scala_3_client: + - generated/app/ApicollectiveApibuilderGeneratorV0Client.scala apibuilder-spec: anorm_2_8_parsers: - api/app/generated/ApicollectiveApibuilderSpecV0Conversions.scala - api/app/generated/ApicollectiveApibuilderSpecV0Parsers.scala - play_2_8_client: - - generated/app/ApicollectiveApibuilderSpecV0Client.scala play_2_8_mock_client: - generated/app/ApicollectiveApibuilderSpecV0MockClient.scala + play_2_9_scala_3_client: + - generated/app/ApicollectiveApibuilderSpecV0Client.scala apibuilder-task: - play_2_8_client: - - generated/app/ApicollectiveApibuilderTaskV0Client.scala play_2_8_mock_client: - generated/app/ApicollectiveApibuilderTaskV0MockClient.scala + play_2_9_scala_3_client: + - generated/app/ApicollectiveApibuilderTaskV0Client.scala diff --git a/.apibuilder/config b/.apibuilder/config index d04875e16..86d66893b 100644 --- a/.apibuilder/config +++ b/.apibuilder/config @@ -3,30 +3,31 @@ code: apibuilder-api: version: latest generators: - play_2_8_client: generated/app + play_2_9_scala_3_client: generated/app play_2_x_routes: api/conf/routes apibuilder-api-json: version: latest generators: - play_2_x_json: core/src/main/scala/core/generated + play_2_x_scala_3_json: core/app/generated apibuilder-spec: version: latest generators: - play_2_8_client: generated/app + play_2_x_standalone_json: lib/src/main/scala/generated + play_2_9_scala_3_client: generated/app play_2_8_mock_client: generated/app apibuilder-common: version: latest generators: - play_2_8_client: generated/app + play_2_9_scala_3_client: generated/app play_2_8_mock_client: generated/app apibuilder-generator: version: latest generators: - play_2_8_client: generated/app + play_2_9_scala_3_client: generated/app play_2_8_mock_client: generated/app apibuilder-task: version: latest generators: - play_2_8_client: generated/app + play_2_9_scala_3_client: generated/app play_2_8_mock_client: generated/app diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7fe221f89..f583db7cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: java: [ '17' ] - scala: [ '2.13.11' ] + scala: [ '3.4.2' ] steps: - uses: actions/checkout@v2 - name: Set up JDK diff --git a/.scalafmt.conf b/.scalafmt.conf new file mode 100644 index 000000000..45c747752 --- /dev/null +++ b/.scalafmt.conf @@ -0,0 +1,9 @@ +version = 3.5.9 +runner.dialect=scala213 +maxColumn = 120 +continuationIndent.callSite = 2 +continuationIndent.defnSite = 2 +continuationIndent.ctorSite = 2 +continuationIndent.extendSite = 2 +align.preset = none +project.excludePaths = [ "glob:**/generated/**" ] diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 11ee309bc..000000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: scala -scala: - - 2.13.8 -jdk: - - openjdk13 -cache: - directories: - - $HOME/.ivy2/cache - - $HOME/.sbt - - $HOME/.cache/coursier -services: - - docker -before_script: - - docker run -d -p 127.0.0.1:7659:5432 flowcommerce/apibuilder-postgresql:latest-pg15 -script: - - CONF_APIBUILDER_API_HOST=http://localhost:9001 sbt ++$TRAVIS_SCALA_VERSION clean compile test -branches: - only: - - main -before_cache: - - rm -fv $HOME/.ivy2/.sbt.ivy.lock - - find $HOME/.ivy2/cache -name "ivydata-*.properties" -print -delete - - find $HOME/.sbt -name "*.lock" -print -delete diff --git a/README.md b/README.md index f41f04bc1..29c263412 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![Build Status](https://travis-ci.org/apicollective/apibuilder.svg?branch=main)](https://travis-ci.org/apicollective/apibuilder) -apibuilder +API Builder ========== Simple, Comprehensive Tooling for Modern APIs. diff --git a/TODO b/TODO index a9cae3d01..8edc05a62 100644 --- a/TODO +++ b/TODO @@ -27,7 +27,7 @@ inserting duplicate records. API changes - generate history of field reordering [warn] /web/apidoc/api/app/db/generators/ServicesDao.scala:118: method apply in trait WithResult is deprecated: Use [[fold]], [[foldWhile]] or [[withResult]] instead, which manages resources and memory -[warn] SQL(sql).on(bind: _*)().toList.map { fromRow(_) }.toSeq +[warn] SQL(sql).on(bind*)().toList.map { fromRow(_) }.toSeq Consider supporting (from swagger): - parameter locations: header, cookie diff --git a/api/app/controllers/ApiBuilderController.scala b/api/app/controllers/ApiBuilderController.scala index 1d601509e..37301cc92 100644 --- a/api/app/controllers/ApiBuilderController.scala +++ b/api/app/controllers/ApiBuilderController.scala @@ -129,8 +129,8 @@ class AnonymousActionBuilder @Inject()( def invokeBlock[A]( request: Request[A], - block: (AnonymousRequest[A] - ) => Future[Result]): Future[Result] = { + block: AnonymousRequest[A] => Future[Result] + ): Future[Result] = { block( AnonymousRequest( user = requestAuthenticationUtil.user(request.headers), @@ -149,8 +149,8 @@ class IdentifiedActionBuilder @Inject()( def invokeBlock[A]( request: Request[A], - block: (IdentifiedRequest[A] - ) => Future[Result]): Future[Result] = { + block: IdentifiedRequest[A] => Future[Result] + ): Future[Result] = { requestAuthenticationUtil.user(request.headers) match { case None => Future.successful(Results.Unauthorized) case Some(user) => block(IdentifiedRequest(user, request)) diff --git a/api/app/controllers/Attributes.scala b/api/app/controllers/Attributes.scala index 2c020f502..39e175b99 100644 --- a/api/app/controllers/Attributes.scala +++ b/api/app/controllers/Attributes.scala @@ -20,7 +20,7 @@ class Attributes @Inject() ( name: Option[String], limit: Long = 25, offset: Long = 0 - ) = Anonymous { _ => + ): Action[AnyContent] = Anonymous { _ => val attributes = attributesDao.findAll( guid = guid, name = name, @@ -30,14 +30,14 @@ class Attributes @Inject() ( Ok(Json.toJson(attributes)) } - def getByName(name: String) = Action { _ => + def getByName(name: String): Action[AnyContent] = Action { _ => attributesDao.findByName(name) match { case None => NotFound case Some(attribute) => Ok(Json.toJson(attribute)) } } - def post() = Identified(parse.json) { request => + def post(): Action[JsValue] = Identified(parse.json) { request => request.body.validate[AttributeForm] match { case e: JsError => { UnprocessableEntity(Json.toJson(Validation.invalidJson(e))) @@ -57,7 +57,7 @@ class Attributes @Inject() ( } } - def deleteByName(name: String) = Identified { request => + def deleteByName(name: String): Action[AnyContent] = Identified { request => attributesDao.findByName(name) match { case None => { NotFound diff --git a/api/app/controllers/Authentications.scala b/api/app/controllers/Authentications.scala index 02f0d735b..1408f2d90 100644 --- a/api/app/controllers/Authentications.scala +++ b/api/app/controllers/Authentications.scala @@ -15,7 +15,7 @@ class Authentications @Inject() ( usersDao: UsersDao ) extends ApiBuilderController { - def getSessionById(sessionId: String) = Anonymous { _ => + def getSessionById(sessionId: String): Action[AnyContent] = Anonymous { _ => sessionsDao.findById(sessionId) match { case None => NotFound case Some(session) => { diff --git a/api/app/controllers/BatchDownloadApplications.scala b/api/app/controllers/BatchDownloadApplications.scala index 749c03d31..4dea3e5d8 100644 --- a/api/app/controllers/BatchDownloadApplications.scala +++ b/api/app/controllers/BatchDownloadApplications.scala @@ -2,10 +2,12 @@ package controllers import cats.data.Validated.{Invalid, Valid} import io.apibuilder.api.v0.models.BatchDownloadApplicationsForm -import io.apibuilder.api.v0.models.json._ +import io.apibuilder.api.v0.models.json.* + import javax.inject.{Inject, Singleton} import lib.Validation import play.api.libs.json.Json +import play.api.mvc.Action import services.BatchDownloadApplicationsService @Singleton @@ -14,7 +16,7 @@ class BatchDownloadApplications @Inject() ( service: BatchDownloadApplicationsService, ) extends ApiBuilderController { - def post(orgKey: String) = Anonymous(parse.json[BatchDownloadApplicationsForm]) { request => + def post(orgKey: String): Action[BatchDownloadApplicationsForm] = Anonymous(parse.json[BatchDownloadApplicationsForm]) { request => service.process(request.authorization, orgKey, request.body) match { case Valid(result) => Created(Json.toJson(result)) case Invalid(errors) => Conflict(Json.toJson(Validation.errors(errors))) diff --git a/api/app/controllers/Changes.scala b/api/app/controllers/Changes.scala index 450c13513..e83d54a6b 100644 --- a/api/app/controllers/Changes.scala +++ b/api/app/controllers/Changes.scala @@ -20,7 +20,7 @@ class Changes @Inject() ( `type`: Option[String], limit: Long = 25, offset: Long = 0 - ) = Anonymous { request => + ): Action[AnyContent] = Anonymous { request => val changes = changesDao.findAll( request.authorization, organizationKey = orgKey, diff --git a/api/app/controllers/Code.scala b/api/app/controllers/Code.scala index 44b55c6ff..d7500cee6 100644 --- a/api/app/controllers/Code.scala +++ b/api/app/controllers/Code.scala @@ -132,7 +132,7 @@ class Code @Inject() ( @nowarn private def _invoke( - request: AnonymousRequest[_], + request: AnonymousRequest[?], params: CodeParams, data: InvocationFormData, generatorKey: String @@ -191,7 +191,7 @@ class Code @Inject() ( } private def invocationForm[T]( - request: AnonymousRequest[_], + request: AnonymousRequest[?], params: CodeParams ): Either[Seq[String], InvocationFormData] = { versionsDao.findVersion(request.authorization, params.orgKey, params.applicationKey, params.versionName) diff --git a/api/app/controllers/Domains.scala b/api/app/controllers/Domains.scala index 1b4fc185d..745d8f19b 100644 --- a/api/app/controllers/Domains.scala +++ b/api/app/controllers/Domains.scala @@ -15,7 +15,7 @@ class Domains @Inject() ( organizationDomainsDao: OrganizationDomainsDao ) extends ApiBuilderController { - def post(orgKey: String) = Identified(parse.json) { request => + def post(orgKey: String): Action[JsValue] = Identified(parse.json) { request => withOrgAdmin(request.user, orgKey) { org => request.body.validate[Domain] match { case e: JsError => { @@ -40,7 +40,7 @@ class Domains @Inject() ( } } - def deleteByName(orgKey: String, name: String) = Identified { request => + def deleteByName(orgKey: String, name: String): Action[AnyContent] = Identified { request => withOrgAdmin(request.user, orgKey) { org => org.domains.find(_.name == name).foreach { domain => organizationDomainsDao.findAll(organizationGuid = Some(org.guid), domain = Some(domain.name)).foreach { orgDomain => diff --git a/api/app/controllers/GeneratorServices.scala b/api/app/controllers/GeneratorServices.scala index acc6bebb3..66646aa7f 100644 --- a/api/app/controllers/GeneratorServices.scala +++ b/api/app/controllers/GeneratorServices.scala @@ -27,7 +27,7 @@ class GeneratorServices @Inject() ( generatorKey: Option[String], limit: Long = 25, offset: Long = 0 - ) = Anonymous { request => + ): Action[AnyContent] = Anonymous { request => val services = servicesDao.findAll( request.authorization, guid = guid, @@ -39,14 +39,14 @@ class GeneratorServices @Inject() ( Ok(Json.toJson(services)) } - def getByGuid(guid: UUID) = Anonymous { request => + def getByGuid(guid: UUID): Action[AnyContent] = Anonymous { request => servicesDao.findByGuid(request.authorization, guid) match { case None => NotFound case Some(service) => Ok(Json.toJson(service)) } } - def post() = Identified(parse.json) { request => + def post(): Action[JsValue] = Identified(parse.json) { request => request.body.validate[GeneratorServiceForm] match { case e: JsError => { Conflict(Json.toJson(Validation.invalidJson(e))) @@ -78,7 +78,7 @@ class GeneratorServices @Inject() ( def deleteByGuid( guid: UUID - ) = Identified { request => + ): Action[AnyContent] = Identified { request => servicesDao.findByGuid(request.authorization, guid) match { case None => { NotFound diff --git a/api/app/controllers/Items.scala b/api/app/controllers/Items.scala index 4df5afe7c..d7d181af2 100644 --- a/api/app/controllers/Items.scala +++ b/api/app/controllers/Items.scala @@ -17,7 +17,7 @@ class Items @Inject() ( q: Option[String], limit: Long = 25, offset: Long = 0 - ) = Anonymous { request => + ): Action[AnyContent] = Anonymous { request => val items = itemsDao.findAll( request.authorization, q = q, @@ -29,7 +29,7 @@ class Items @Inject() ( def getByGuid( guid: UUID - ) = Anonymous { request => + ): Action[AnyContent] = Anonymous { request => itemsDao.findByGuid(request.authorization, guid) match { case None => NotFound case Some(item) => Ok(Json.toJson(item)) diff --git a/api/app/controllers/MembershipRequests.scala b/api/app/controllers/MembershipRequests.scala index 5e9a90409..c0f2066a4 100644 --- a/api/app/controllers/MembershipRequests.scala +++ b/api/app/controllers/MembershipRequests.scala @@ -58,8 +58,7 @@ class MembershipRequests @Inject() ( case e: JsError => { Conflict(Json.toJson(Validation.error(e.toString))) } - case s: JsSuccess[MembershipRequestForm] => { - val form = s.get + case JsSuccess(form: MembershipRequestForm, _) => { organizationsDao.findByGuid(request.authorization, form.org_guid) match { case None => { Conflict(Json.toJson(Validation.error("Organization not found or not authorized to make changes to this org"))) diff --git a/api/app/controllers/PasswordResetRequests.scala b/api/app/controllers/PasswordResetRequests.scala index 8278f8c04..4677a85da 100644 --- a/api/app/controllers/PasswordResetRequests.scala +++ b/api/app/controllers/PasswordResetRequests.scala @@ -15,7 +15,7 @@ class PasswordResetRequests @Inject() ( usersDao: UsersDao ) extends ApiBuilderController { - def post() = Anonymous(parse.json) { request => + def post(): Action[JsValue] = Anonymous(parse.json) { request => request.body.validate[PasswordResetRequest] match { case e: JsError => { Conflict(Json.toJson(Validation.invalidJson(e))) diff --git a/api/app/controllers/PasswordResets.scala b/api/app/controllers/PasswordResets.scala index 69133bb4b..6c4469dbe 100644 --- a/api/app/controllers/PasswordResets.scala +++ b/api/app/controllers/PasswordResets.scala @@ -18,7 +18,7 @@ class PasswordResets @Inject() ( userPasswordsDao: UserPasswordsDao ) extends ApiBuilderController { - def post() = Anonymous(parse.json) { request => + def post(): Action[JsValue] = Anonymous(parse.json) { request => request.body.validate[PasswordReset] match { case e: JsError => { Conflict(Json.toJson(Validation.invalidJson(e))) diff --git a/api/app/controllers/Subscriptions.scala b/api/app/controllers/Subscriptions.scala index bfbf05150..70159ceae 100644 --- a/api/app/controllers/Subscriptions.scala +++ b/api/app/controllers/Subscriptions.scala @@ -1,16 +1,15 @@ package controllers import db.SubscriptionsDao -import lib.Validation -import io.apibuilder.api.v0.models.{Publication, SubscriptionForm} import io.apibuilder.api.v0.models.json._ +import io.apibuilder.api.v0.models.{Publication, SubscriptionForm} +import lib.Validation import models.SubscriptionModel - -import javax.inject.{Inject, Singleton} -import play.api.mvc._ import play.api.libs.json._ +import play.api.mvc._ import java.util.UUID +import javax.inject.{Inject, Singleton} @Singleton class Subscriptions @Inject() ( diff --git a/api/app/controllers/Users.scala b/api/app/controllers/Users.scala index a2a70e179..6bac984d2 100644 --- a/api/app/controllers/Users.scala +++ b/api/app/controllers/Users.scala @@ -1,16 +1,17 @@ package controllers import io.apibuilder.api.v0.models.{User, UserForm, UserUpdateForm} -import io.apibuilder.api.v0.models.json._ +import io.apibuilder.api.v0.models.json.* import lib.Validation import util.SessionHelper import db.{UserPasswordsDao, UsersDao} import javax.inject.Inject -import play.api.libs.json.{JsArray, JsBoolean, JsError, JsObject, JsString, JsSuccess, Json, Reads} +import play.api.libs.json.{JsArray, JsBoolean, JsError, JsObject, JsString, JsSuccess, JsValue, Json, Reads} import java.util.UUID import play.api.libs.ws.WSClient +import play.api.mvc.{Action, AnyContent} import scala.concurrent.Future @@ -35,7 +36,7 @@ class Users @Inject() ( email: Option[String], nickname: Option[String], token: Option[String] - ) = Identified { request => + ): Action[AnyContent] = Identified { request => if (!Seq(guid, email, nickname, token).exists(_.isDefined)) { // require system user to show more then one user requireSystemUser(request.user) @@ -50,7 +51,7 @@ class Users @Inject() ( Ok(Json.toJson(users)) } - def getByGuid(guid: UUID) = Identified { request => + def getByGuid(guid: UUID): Action[AnyContent] = Identified { request => requireSystemUser(request.user) usersDao.findByGuid(guid) match { case None => NotFound @@ -58,13 +59,12 @@ class Users @Inject() ( } } - def post() = Anonymous(parse.json) { request => + def post(): Action[JsValue] = Anonymous(parse.json) { request => request.body.validate[UserForm] match { case e: JsError => { Conflict(Json.toJson(Validation.invalidJson(e))) } - case s: JsSuccess[UserForm] => { - val form = s.get + case JsSuccess(form: UserForm, _) => { usersDao.validateNewUser(form) match { case Nil => { val user = usersDao.create(form) @@ -78,7 +78,7 @@ class Users @Inject() ( } } - def putByGuid(guid: UUID) = Identified(parse.json) { request => + def putByGuid(guid: UUID): Action[JsValue] = Identified(parse.json) { request => request.body.validate[UserUpdateForm] match { case e: JsError => { Conflict(Json.toJson(Validation.invalidJson(e))) @@ -120,15 +120,13 @@ class Users @Inject() ( } } - def postAuthenticate() = Anonymous(parse.json) { request => + def postAuthenticate(): Action[JsValue] = Anonymous(parse.json) { request => request.body.validate[UserAuthenticationForm] match { case e: JsError => { Conflict(Json.toJson(Validation.invalidJson(e))) } - case s: JsSuccess[UserAuthenticationForm] => { - val form = s.get + case JsSuccess(form: UserAuthenticationForm, _) => { usersDao.findByEmail(form.email) match { - case None => { Conflict(Json.toJson(Validation.userAuthorizationFailed())) } @@ -145,14 +143,13 @@ class Users @Inject() ( } } - def postAuthenticateGithub() = Action.async(parse.json) { request => + def postAuthenticateGithub(): Action[JsValue] = Action.async(parse.json) { request => request.body.validate[GithubAuthenticationForm] match { case e: JsError => Future.successful { Conflict(Json.toJson(Validation.invalidJson(e))) } - case s: JsSuccess[GithubAuthenticationForm] => { - val token = s.get.token - val headers = "Authorization" -> s"Bearer $token" + case JsSuccess(form: GithubAuthenticationForm, _) => { + val headers = "Authorization" -> s"Bearer ${form.token}" for { userResponse <- wsClient.url("https://api.github.com/user").addHttpHeaders(headers).get() diff --git a/api/app/db/ItemsDao.scala b/api/app/db/ItemsDao.scala index 7b1f576a6..ec3f6e737 100644 --- a/api/app/db/ItemsDao.scala +++ b/api/app/db/ItemsDao.scala @@ -67,7 +67,7 @@ class ItemsDao @Inject() ( "detail" -> Json.toJson(detail).toString, "label" -> label.trim, "description" -> description.map(_.trim).map(Text.truncate(_)), - "content" -> content.trim.toLowerCase + "content" -> content.trim.toLowerCase, ).execute() } } diff --git a/api/app/db/OrganizationsDao.scala b/api/app/db/OrganizationsDao.scala index 7db93d7b7..00dc20de3 100644 --- a/api/app/db/OrganizationsDao.scala +++ b/api/app/db/OrganizationsDao.scala @@ -195,7 +195,7 @@ class OrganizationsDao @Inject() ( name = form.name.trim, namespace = form.namespace.trim, visibility = form.visibility, - domains = form.domains.getOrElse(Nil).map(Domain), + domains = form.domains.getOrElse(Nil).map(Domain(_)), audit = Audit( createdAt = DateTime.now, createdBy = ReferenceGuid(user.guid), diff --git a/api/app/db/TokensDao.scala b/api/app/db/TokensDao.scala index bbf071590..ab64d3ae9 100644 --- a/api/app/db/TokensDao.scala +++ b/api/app/db/TokensDao.scala @@ -99,7 +99,7 @@ class TokensDao @Inject() ( equals("tokens.guid", guid). as(SqlParser.str("token").*). headOption. - map(CleartextToken) + map(CleartextToken(_)) } } diff --git a/api/app/db/UserPasswordsDao.scala b/api/app/db/UserPasswordsDao.scala index 3ec29ab59..552d72709 100644 --- a/api/app/db/UserPasswordsDao.scala +++ b/api/app/db/UserPasswordsDao.scala @@ -1,95 +1,24 @@ package db +import anorm.* +import com.mbryzek.cipher.{CipherLibraryMindrot, Ciphers, HashedValue} import io.apibuilder.api.v0.models.{Error, User} +import io.flow.postgresql.Query import lib.Validation -import anorm._ -import javax.inject.{Inject, Singleton} +import play.api.db.* -import play.api.db._ -import java.util.UUID import java.sql.Connection +import java.util.UUID +import javax.inject.{Inject, Singleton} -import io.flow.postgresql.Query -import org.mindrot.jbcrypt.BCrypt -import org.apache.commons.codec.binary.Base64 - -private[db] case class HashedPassword(hash: String) - -sealed trait PasswordAlgorithm { - - /** - * Uniquely identifies this password algorithm - */ - def key: String - - /** - * Hashes the provided String, returning the hashed value - */ - def hash(password: String): HashedPassword - - /** - * Check if a cleartext password is valid - */ - def check(candidate: String, hashed: String): Boolean - -} - -case class BcryptPasswordAlgorithm(override val key: String) extends PasswordAlgorithm { - - private val LogRounds = 13 - - override def hash(password: String): HashedPassword = { - val salt = BCrypt.gensalt(LogRounds) - HashedPassword(BCrypt.hashpw(password, salt)) - } - - override def check(candidate: String, hashed: String): Boolean = { - BCrypt.checkpw(candidate, hashed) - } - -} - -/** - * Used only when fetching unknown keys from DB but will fail if you try to hash - */ -private[db] case class UnknownPasswordAlgorithm(override val key: String) extends PasswordAlgorithm { - - override def hash(password: String): HashedPassword = { - sys.error("Unsupported operation for UnknownPasswordAlgorithm") - } - - override def check(candidate: String, hashed: String) = false - -} - -object PasswordAlgorithm { - - private[db] val All = Seq( - BcryptPasswordAlgorithm("bcrypt"), - UnknownPasswordAlgorithm("unknown") - ) - - val Latest: PasswordAlgorithm = fromString("bcrypt").getOrElse { - sys.error("Could not find latest algorithm") - } - - private[db] val Unknown: PasswordAlgorithm = fromString("unknown").getOrElse { - sys.error("Could not find unknown algorithm") - } - - def fromString(value: String): Option[PasswordAlgorithm] = { - All.find(_.key == value) - } - -} - -case class UserPassword(guid: UUID, userGuid: UUID, algorithm: PasswordAlgorithm, hash: String) +case class UserPassword(guid: UUID, userGuid: UUID, algorithmKey: String, base64EncodedHash: String) @Singleton class UserPasswordsDao @Inject() ( @NamedDatabase("default") db: Database ) { + private val ciphers: Ciphers = Ciphers() private val MinLength = 5 private val BaseQuery = Query( @@ -141,14 +70,14 @@ class UserPasswordsDao @Inject() ( assert(errors.isEmpty, errors.map(_.message).mkString("\n")) val guid = UUID.randomUUID - val algorithm = PasswordAlgorithm.Latest + val algorithm = ciphers.latest val hashedPassword = algorithm.hash(cleartextPassword) SQL(InsertQuery).on( "guid" -> guid, "user_guid" -> userGuid, "algorithm_key" -> algorithm.key, - "hash" -> new String(Base64.encodeBase64(hashedPassword.hash.getBytes)), + "hash" -> hashedPassword.hash, "created_by_guid" -> creatingUserGuid, "updated_by_guid" -> creatingUserGuid ).execute() @@ -161,7 +90,18 @@ class UserPasswordsDao @Inject() ( def isValid(userGuid: UUID, cleartextPassword: String): Boolean = { findByUserGuid(userGuid) match { case None => false - case Some(up: UserPassword) => up.algorithm.check(cleartextPassword, up.hash) + case Some(up) => { + ciphers.libraries.find(_.key == up.algorithmKey) match { + case None => false + case Some(al) => { + al.isValid( + plaintext = cleartextPassword, + hash = up.base64EncodedHash, + salt = None + ) + } + } + } } } @@ -184,10 +124,8 @@ class UserPasswordsDao @Inject() ( UserPassword( guid = guid, userGuid = userGuid, - algorithm = PasswordAlgorithm.fromString(algorithmKey).getOrElse { - sys.error(s"Invalid algorithmKey[$algorithmKey] for userGuid[$userGuid]") - }, - hash = new String(Base64.decodeBase64(hash.getBytes)) + algorithmKey = algorithmKey, + base64EncodedHash = hash ) } } diff --git a/api/app/db/VersionsDao.scala b/api/app/db/VersionsDao.scala index f13aa9074..b8d2863b6 100644 --- a/api/app/db/VersionsDao.scala +++ b/api/app/db/VersionsDao.scala @@ -300,7 +300,7 @@ class VersionsDao @Inject() ( guid = guid, applicationGuid = applicationGuid, version = version, - original = (originalType.map(OriginalType.apply), originalData).mapN(Original), + original = (originalType.map(OriginalType.apply), originalData).mapN(Original(_, _)), serviceJson = serviceJson, audit = Audit( createdAt = createdAt, diff --git a/api/app/db/WatchesDao.scala b/api/app/db/WatchesDao.scala index 6f671310f..5fa91852b 100644 --- a/api/app/db/WatchesDao.scala +++ b/api/app/db/WatchesDao.scala @@ -52,7 +52,7 @@ class WatchesDao @Inject() ( ( usersDao.findByGuid(form.userGuid).toValidNec(Validation.singleError("User not found")), applicationsDao.findByOrganizationKeyAndApplicationKey(auth, form.organizationKey, form.applicationKey).toValidNec(Validation.singleError(s"Application[${form.applicationKey}] not found")) - ).mapN(ValidatedWatchForm) + ).mapN(ValidatedWatchForm(_, _)) } private def findByApplicationGuidAndUserGuid(applicationGuid: UUID, userGuid: UUID) = { diff --git a/api/app/db/generated/GeneratorApibuilderSessionsDao.scala b/api/app/db/generated/GeneratorApibuilderSessionsDao.scala index 63217b04a..f6b90ff46 100644 --- a/api/app/db/generated/GeneratorApibuilderSessionsDao.scala +++ b/api/app/db/generated/GeneratorApibuilderSessionsDao.scala @@ -103,57 +103,57 @@ class SessionsDao @Inject() ( bind("hash_code", form.hashCode()) } - def insert(updatedBy: UUID, form: SessionForm) { + def insert(updatedBy: UUID, form: SessionForm): Unit = { db.withConnection { implicit c => insert(c, updatedBy, form) } } - def insert(implicit c: Connection, updatedBy: UUID, form: SessionForm) { + def insert(implicit c: Connection, updatedBy: UUID, form: SessionForm): Unit = { bindQuery(InsertQuery, form). bind("id", form.id). - anormSql.execute() + anormSql().execute() } - def updateIfChangedById(updatedBy: UUID, id: String, form: SessionForm) { + def updateIfChangedById(updatedBy: UUID, id: String, form: SessionForm): Unit ={ if (!findById(id).map(_.form).contains(form)) { updateById(updatedBy, id, form) } } - def updateById(updatedBy: UUID, id: String, form: SessionForm) { + def updateById(updatedBy: UUID, id: String, form: SessionForm): Unit = { db.withConnection { implicit c => updateById(c, updatedBy, id, form) } } - def updateById(implicit c: Connection, updatedBy: UUID, id: String, form: SessionForm) { + def updateById(implicit c: Connection, updatedBy: UUID, id: String, form: SessionForm): Unit = { bindQuery(UpdateQuery, form). bind("id", id). - anormSql.execute() + anormSql().execute() } - def update(updatedBy: UUID, existing: Session, form: SessionForm) { + def update(updatedBy: UUID, existing: Session, form: SessionForm): Unit = { db.withConnection { implicit c => update(c, updatedBy, existing, form) } } - def update(implicit c: Connection, updatedBy: UUID, existing: Session, form: SessionForm) { + def update(implicit c: Connection, updatedBy: UUID, existing: Session, form: SessionForm): Unit = { updateById(c, updatedBy, existing.id, form) } - def delete(deletedBy: UUID, session: Session) { + def delete(deletedBy: UUID, session: Session): Unit = { dbHelpers.delete(deletedBy, session.id) } - def deleteById(deletedBy: UUID, id: String) { + def deleteById(deletedBy: UUID, id: String): Unit = { db.withConnection { implicit c => deleteById(c, deletedBy, id) } } - def deleteById(c: java.sql.Connection, deletedBy: UUID, id: String) { + def deleteById(c: java.sql.Connection, deletedBy: UUID, id: String): Unit = { dbHelpers.delete(c, deletedBy, id) } diff --git a/api/app/db/generated/PsqlApibuilderGeneratorInvocationsDao.scala b/api/app/db/generated/PsqlApibuilderGeneratorInvocationsDao.scala index 052b1e484..4d813e176 100644 --- a/api/app/db/generated/PsqlApibuilderGeneratorInvocationsDao.scala +++ b/api/app/db/generated/PsqlApibuilderGeneratorInvocationsDao.scala @@ -1,8 +1,8 @@ package db.generated import anorm._ +import com.mbryzek.util.IdGenerator import io.flow.postgresql.{OrderBy, Query} -import io.flow.util.IdGenerator import java.sql.Connection import java.util.UUID import javax.inject.{Inject, Singleton} @@ -166,7 +166,7 @@ class GeneratorInvocationsDao @Inject() ( override val db: Database ) extends BaseGeneratorInvocationsDao { - private val idGenerator = IdGenerator("gni") + private val idGenerator = com.mbryzek.util.IdGenerator("gni") def randomId(): String = idGenerator.randomId() @@ -232,7 +232,7 @@ class GeneratorInvocationsDao @Inject() ( if (forms.nonEmpty) { val ids = forms.map(_ => randomId()) val params = ids.zip(forms).map { case (id, form) => toNamedParameter(updatedBy, id, form) } - BatchSql(InsertQuery.sql(), params.head, params.tail: _*).execute()(c) + BatchSql(InsertQuery.sql(), params.head, params.tail*).execute()(c) ids } else { Nil @@ -278,7 +278,7 @@ class GeneratorInvocationsDao @Inject() ( def updateBatchWithConnection(c: Connection, updatedBy: UUID, idsAndForms: Seq[(String, GeneratorInvocationForm)]): Unit = { if (idsAndForms.nonEmpty) { val params = idsAndForms.map { case (id, form) => toNamedParameter(updatedBy, id, form) } - BatchSql(UpdateQuery.sql(), params.head, params.tail: _*).execute()(c) + BatchSql(UpdateQuery.sql(), params.head, params.tail*).execute()(c) () } } diff --git a/api/app/db/generated/PsqlApibuilderTasksDao.scala b/api/app/db/generated/PsqlApibuilderTasksDao.scala index 8e7334734..e3f31c7c2 100644 --- a/api/app/db/generated/PsqlApibuilderTasksDao.scala +++ b/api/app/db/generated/PsqlApibuilderTasksDao.scala @@ -403,7 +403,7 @@ class TasksDao @Inject() ( def upsertBatchByTypeIdAndType(c: Connection, updatedBy: UUID, forms: Seq[TaskForm]): Unit = { if (forms.nonEmpty) { val params = forms.map(toNamedParameter(updatedBy, _)) - BatchSql(UpsertQuery.sql(), params.head, params.tail: _*).execute()(c) + BatchSql(UpsertQuery.sql(), params.head, params.tail*).execute()(c) () } } @@ -447,7 +447,7 @@ class TasksDao @Inject() ( def updateBatchWithConnection(c: Connection, updatedBy: UUID, forms: Seq[TaskForm]): Unit = { if (forms.nonEmpty) { val params = forms.map(toNamedParameter(updatedBy, _)) - BatchSql(UpdateQuery.sql(), params.head, params.tail: _*).execute()(c) + BatchSql(UpdateQuery.sql(), params.head, params.tail*).execute()(c) () } } diff --git a/api/app/generated/ApicollectiveApibuilderApiV0Conversions.scala b/api/app/generated/ApicollectiveApibuilderApiV0Conversions.scala index 1fd8c1788..f62e40379 100644 --- a/api/app/generated/ApicollectiveApibuilderApiV0Conversions.scala +++ b/api/app/generated/ApicollectiveApibuilderApiV0Conversions.scala @@ -1,14 +1,13 @@ /** * Generated by API Builder - https://www.apibuilder.io * Service version: 0.16.50 - * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-api/latest/anorm_2_8_parsers + * User agent: apibuilder localhost 9000/apicollective/apibuilder-api/latest/anorm_2_8_scala_3_parsers */ package io.apibuilder.api.v0.anorm.conversions { import anorm.{Column, MetaDataItem, TypeDoesNotMatch} import play.api.libs.json.{JsArray, JsObject, JsValue} import scala.util.{Failure, Success, Try} - import play.api.libs.json.JodaReads._ /** * Conversions to collections of objects using JSON. @@ -52,152 +51,10 @@ package io.apibuilder.api.v0.anorm.conversions { } object Types { - import io.apibuilder.api.v0.models.json._ - implicit val columnToSeqApibuilderApiAppSortBy: Column[Seq[_root_.io.apibuilder.api.v0.models.AppSortBy]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.AppSortBy]] } - implicit val columnToMapApibuilderApiAppSortBy: Column[Map[String, _root_.io.apibuilder.api.v0.models.AppSortBy]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.AppSortBy]] } - implicit val columnToSeqApibuilderApiOriginalType: Column[Seq[_root_.io.apibuilder.api.v0.models.OriginalType]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.OriginalType]] } - implicit val columnToMapApibuilderApiOriginalType: Column[Map[String, _root_.io.apibuilder.api.v0.models.OriginalType]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.OriginalType]] } - implicit val columnToSeqApibuilderApiPublication: Column[Seq[_root_.io.apibuilder.api.v0.models.Publication]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Publication]] } - implicit val columnToMapApibuilderApiPublication: Column[Map[String, _root_.io.apibuilder.api.v0.models.Publication]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Publication]] } - implicit val columnToSeqApibuilderApiSortOrder: Column[Seq[_root_.io.apibuilder.api.v0.models.SortOrder]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.SortOrder]] } - implicit val columnToMapApibuilderApiSortOrder: Column[Map[String, _root_.io.apibuilder.api.v0.models.SortOrder]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.SortOrder]] } - implicit val columnToSeqApibuilderApiVisibility: Column[Seq[_root_.io.apibuilder.api.v0.models.Visibility]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Visibility]] } - implicit val columnToMapApibuilderApiVisibility: Column[Map[String, _root_.io.apibuilder.api.v0.models.Visibility]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Visibility]] } - implicit val columnToSeqApibuilderApiApplication: Column[Seq[_root_.io.apibuilder.api.v0.models.Application]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Application]] } - implicit val columnToMapApibuilderApiApplication: Column[Map[String, _root_.io.apibuilder.api.v0.models.Application]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Application]] } - implicit val columnToSeqApibuilderApiApplicationForm: Column[Seq[_root_.io.apibuilder.api.v0.models.ApplicationForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.ApplicationForm]] } - implicit val columnToMapApibuilderApiApplicationForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.ApplicationForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.ApplicationForm]] } - implicit val columnToSeqApibuilderApiApplicationMetadata: Column[Seq[_root_.io.apibuilder.api.v0.models.ApplicationMetadata]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.ApplicationMetadata]] } - implicit val columnToMapApibuilderApiApplicationMetadata: Column[Map[String, _root_.io.apibuilder.api.v0.models.ApplicationMetadata]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.ApplicationMetadata]] } - implicit val columnToSeqApibuilderApiApplicationMetadataVersion: Column[Seq[_root_.io.apibuilder.api.v0.models.ApplicationMetadataVersion]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.ApplicationMetadataVersion]] } - implicit val columnToMapApibuilderApiApplicationMetadataVersion: Column[Map[String, _root_.io.apibuilder.api.v0.models.ApplicationMetadataVersion]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.ApplicationMetadataVersion]] } - implicit val columnToSeqApibuilderApiApplicationSummary: Column[Seq[_root_.io.apibuilder.api.v0.models.ApplicationSummary]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.ApplicationSummary]] } - implicit val columnToMapApibuilderApiApplicationSummary: Column[Map[String, _root_.io.apibuilder.api.v0.models.ApplicationSummary]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.ApplicationSummary]] } - implicit val columnToSeqApibuilderApiAttribute: Column[Seq[_root_.io.apibuilder.api.v0.models.Attribute]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Attribute]] } - implicit val columnToMapApibuilderApiAttribute: Column[Map[String, _root_.io.apibuilder.api.v0.models.Attribute]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Attribute]] } - implicit val columnToSeqApibuilderApiAttributeForm: Column[Seq[_root_.io.apibuilder.api.v0.models.AttributeForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.AttributeForm]] } - implicit val columnToMapApibuilderApiAttributeForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.AttributeForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.AttributeForm]] } - implicit val columnToSeqApibuilderApiAttributeSummary: Column[Seq[_root_.io.apibuilder.api.v0.models.AttributeSummary]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.AttributeSummary]] } - implicit val columnToMapApibuilderApiAttributeSummary: Column[Map[String, _root_.io.apibuilder.api.v0.models.AttributeSummary]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.AttributeSummary]] } - implicit val columnToSeqApibuilderApiAttributeValue: Column[Seq[_root_.io.apibuilder.api.v0.models.AttributeValue]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.AttributeValue]] } - implicit val columnToMapApibuilderApiAttributeValue: Column[Map[String, _root_.io.apibuilder.api.v0.models.AttributeValue]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.AttributeValue]] } - implicit val columnToSeqApibuilderApiAttributeValueForm: Column[Seq[_root_.io.apibuilder.api.v0.models.AttributeValueForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.AttributeValueForm]] } - implicit val columnToMapApibuilderApiAttributeValueForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.AttributeValueForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.AttributeValueForm]] } - implicit val columnToSeqApibuilderApiAuthentication: Column[Seq[_root_.io.apibuilder.api.v0.models.Authentication]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Authentication]] } - implicit val columnToMapApibuilderApiAuthentication: Column[Map[String, _root_.io.apibuilder.api.v0.models.Authentication]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Authentication]] } - implicit val columnToSeqApibuilderApiBatchDownloadApplicationForm: Column[Seq[_root_.io.apibuilder.api.v0.models.BatchDownloadApplicationForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.BatchDownloadApplicationForm]] } - implicit val columnToMapApibuilderApiBatchDownloadApplicationForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.BatchDownloadApplicationForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.BatchDownloadApplicationForm]] } - implicit val columnToSeqApibuilderApiBatchDownloadApplications: Column[Seq[_root_.io.apibuilder.api.v0.models.BatchDownloadApplications]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.BatchDownloadApplications]] } - implicit val columnToMapApibuilderApiBatchDownloadApplications: Column[Map[String, _root_.io.apibuilder.api.v0.models.BatchDownloadApplications]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.BatchDownloadApplications]] } - implicit val columnToSeqApibuilderApiBatchDownloadApplicationsForm: Column[Seq[_root_.io.apibuilder.api.v0.models.BatchDownloadApplicationsForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.BatchDownloadApplicationsForm]] } - implicit val columnToMapApibuilderApiBatchDownloadApplicationsForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.BatchDownloadApplicationsForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.BatchDownloadApplicationsForm]] } - implicit val columnToSeqApibuilderApiChange: Column[Seq[_root_.io.apibuilder.api.v0.models.Change]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Change]] } - implicit val columnToMapApibuilderApiChange: Column[Map[String, _root_.io.apibuilder.api.v0.models.Change]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Change]] } - implicit val columnToSeqApibuilderApiChangeVersion: Column[Seq[_root_.io.apibuilder.api.v0.models.ChangeVersion]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.ChangeVersion]] } - implicit val columnToMapApibuilderApiChangeVersion: Column[Map[String, _root_.io.apibuilder.api.v0.models.ChangeVersion]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.ChangeVersion]] } - implicit val columnToSeqApibuilderApiCleartextToken: Column[Seq[_root_.io.apibuilder.api.v0.models.CleartextToken]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.CleartextToken]] } - implicit val columnToMapApibuilderApiCleartextToken: Column[Map[String, _root_.io.apibuilder.api.v0.models.CleartextToken]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.CleartextToken]] } - implicit val columnToSeqApibuilderApiCode: Column[Seq[_root_.io.apibuilder.api.v0.models.Code]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Code]] } - implicit val columnToMapApibuilderApiCode: Column[Map[String, _root_.io.apibuilder.api.v0.models.Code]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Code]] } - implicit val columnToSeqApibuilderApiCodeForm: Column[Seq[_root_.io.apibuilder.api.v0.models.CodeForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.CodeForm]] } - implicit val columnToMapApibuilderApiCodeForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.CodeForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.CodeForm]] } - implicit val columnToSeqApibuilderApiDiffBreaking: Column[Seq[_root_.io.apibuilder.api.v0.models.DiffBreaking]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.DiffBreaking]] } - implicit val columnToMapApibuilderApiDiffBreaking: Column[Map[String, _root_.io.apibuilder.api.v0.models.DiffBreaking]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.DiffBreaking]] } - implicit val columnToSeqApibuilderApiDiffNonBreaking: Column[Seq[_root_.io.apibuilder.api.v0.models.DiffNonBreaking]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.DiffNonBreaking]] } - implicit val columnToMapApibuilderApiDiffNonBreaking: Column[Map[String, _root_.io.apibuilder.api.v0.models.DiffNonBreaking]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.DiffNonBreaking]] } - implicit val columnToSeqApibuilderApiDomain: Column[Seq[_root_.io.apibuilder.api.v0.models.Domain]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Domain]] } - implicit val columnToMapApibuilderApiDomain: Column[Map[String, _root_.io.apibuilder.api.v0.models.Domain]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Domain]] } - implicit val columnToSeqApibuilderApiEmailVerificationConfirmationForm: Column[Seq[_root_.io.apibuilder.api.v0.models.EmailVerificationConfirmationForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.EmailVerificationConfirmationForm]] } - implicit val columnToMapApibuilderApiEmailVerificationConfirmationForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.EmailVerificationConfirmationForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.EmailVerificationConfirmationForm]] } - implicit val columnToSeqApibuilderApiError: Column[Seq[_root_.io.apibuilder.api.v0.models.Error]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Error]] } - implicit val columnToMapApibuilderApiError: Column[Map[String, _root_.io.apibuilder.api.v0.models.Error]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Error]] } - implicit val columnToSeqApibuilderApiGeneratorForm: Column[Seq[_root_.io.apibuilder.api.v0.models.GeneratorForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.GeneratorForm]] } - implicit val columnToMapApibuilderApiGeneratorForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.GeneratorForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.GeneratorForm]] } - implicit val columnToSeqApibuilderApiGeneratorService: Column[Seq[_root_.io.apibuilder.api.v0.models.GeneratorService]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.GeneratorService]] } - implicit val columnToMapApibuilderApiGeneratorService: Column[Map[String, _root_.io.apibuilder.api.v0.models.GeneratorService]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.GeneratorService]] } - implicit val columnToSeqApibuilderApiGeneratorServiceForm: Column[Seq[_root_.io.apibuilder.api.v0.models.GeneratorServiceForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.GeneratorServiceForm]] } - implicit val columnToMapApibuilderApiGeneratorServiceForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.GeneratorServiceForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.GeneratorServiceForm]] } - implicit val columnToSeqApibuilderApiGeneratorWithService: Column[Seq[_root_.io.apibuilder.api.v0.models.GeneratorWithService]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.GeneratorWithService]] } - implicit val columnToMapApibuilderApiGeneratorWithService: Column[Map[String, _root_.io.apibuilder.api.v0.models.GeneratorWithService]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.GeneratorWithService]] } - implicit val columnToSeqApibuilderApiItem: Column[Seq[_root_.io.apibuilder.api.v0.models.Item]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Item]] } - implicit val columnToMapApibuilderApiItem: Column[Map[String, _root_.io.apibuilder.api.v0.models.Item]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Item]] } - implicit val columnToSeqApibuilderApiMembership: Column[Seq[_root_.io.apibuilder.api.v0.models.Membership]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Membership]] } - implicit val columnToMapApibuilderApiMembership: Column[Map[String, _root_.io.apibuilder.api.v0.models.Membership]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Membership]] } - implicit val columnToSeqApibuilderApiMembershipRequest: Column[Seq[_root_.io.apibuilder.api.v0.models.MembershipRequest]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.MembershipRequest]] } - implicit val columnToMapApibuilderApiMembershipRequest: Column[Map[String, _root_.io.apibuilder.api.v0.models.MembershipRequest]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.MembershipRequest]] } - implicit val columnToSeqApibuilderApiMoveForm: Column[Seq[_root_.io.apibuilder.api.v0.models.MoveForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.MoveForm]] } - implicit val columnToMapApibuilderApiMoveForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.MoveForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.MoveForm]] } - implicit val columnToSeqApibuilderApiOrganization: Column[Seq[_root_.io.apibuilder.api.v0.models.Organization]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Organization]] } - implicit val columnToMapApibuilderApiOrganization: Column[Map[String, _root_.io.apibuilder.api.v0.models.Organization]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Organization]] } - implicit val columnToSeqApibuilderApiOrganizationForm: Column[Seq[_root_.io.apibuilder.api.v0.models.OrganizationForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.OrganizationForm]] } - implicit val columnToMapApibuilderApiOrganizationForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.OrganizationForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.OrganizationForm]] } - implicit val columnToSeqApibuilderApiOriginal: Column[Seq[_root_.io.apibuilder.api.v0.models.Original]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Original]] } - implicit val columnToMapApibuilderApiOriginal: Column[Map[String, _root_.io.apibuilder.api.v0.models.Original]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Original]] } - implicit val columnToSeqApibuilderApiOriginalForm: Column[Seq[_root_.io.apibuilder.api.v0.models.OriginalForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.OriginalForm]] } - implicit val columnToMapApibuilderApiOriginalForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.OriginalForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.OriginalForm]] } - implicit val columnToSeqApibuilderApiPasswordReset: Column[Seq[_root_.io.apibuilder.api.v0.models.PasswordReset]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.PasswordReset]] } - implicit val columnToMapApibuilderApiPasswordReset: Column[Map[String, _root_.io.apibuilder.api.v0.models.PasswordReset]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.PasswordReset]] } - implicit val columnToSeqApibuilderApiPasswordResetRequest: Column[Seq[_root_.io.apibuilder.api.v0.models.PasswordResetRequest]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.PasswordResetRequest]] } - implicit val columnToMapApibuilderApiPasswordResetRequest: Column[Map[String, _root_.io.apibuilder.api.v0.models.PasswordResetRequest]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.PasswordResetRequest]] } - implicit val columnToSeqApibuilderApiSession: Column[Seq[_root_.io.apibuilder.api.v0.models.Session]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Session]] } - implicit val columnToMapApibuilderApiSession: Column[Map[String, _root_.io.apibuilder.api.v0.models.Session]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Session]] } - implicit val columnToSeqApibuilderApiSubscription: Column[Seq[_root_.io.apibuilder.api.v0.models.Subscription]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Subscription]] } - implicit val columnToMapApibuilderApiSubscription: Column[Map[String, _root_.io.apibuilder.api.v0.models.Subscription]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Subscription]] } - implicit val columnToSeqApibuilderApiSubscriptionForm: Column[Seq[_root_.io.apibuilder.api.v0.models.SubscriptionForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.SubscriptionForm]] } - implicit val columnToMapApibuilderApiSubscriptionForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.SubscriptionForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.SubscriptionForm]] } - implicit val columnToSeqApibuilderApiToken: Column[Seq[_root_.io.apibuilder.api.v0.models.Token]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Token]] } - implicit val columnToMapApibuilderApiToken: Column[Map[String, _root_.io.apibuilder.api.v0.models.Token]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Token]] } - implicit val columnToSeqApibuilderApiTokenForm: Column[Seq[_root_.io.apibuilder.api.v0.models.TokenForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.TokenForm]] } - implicit val columnToMapApibuilderApiTokenForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.TokenForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.TokenForm]] } - implicit val columnToSeqApibuilderApiUser: Column[Seq[_root_.io.apibuilder.api.v0.models.User]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.User]] } - implicit val columnToMapApibuilderApiUser: Column[Map[String, _root_.io.apibuilder.api.v0.models.User]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.User]] } - implicit val columnToSeqApibuilderApiUserForm: Column[Seq[_root_.io.apibuilder.api.v0.models.UserForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.UserForm]] } - implicit val columnToMapApibuilderApiUserForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.UserForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.UserForm]] } - implicit val columnToSeqApibuilderApiUserSummary: Column[Seq[_root_.io.apibuilder.api.v0.models.UserSummary]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.UserSummary]] } - implicit val columnToMapApibuilderApiUserSummary: Column[Map[String, _root_.io.apibuilder.api.v0.models.UserSummary]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.UserSummary]] } - implicit val columnToSeqApibuilderApiUserUpdateForm: Column[Seq[_root_.io.apibuilder.api.v0.models.UserUpdateForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.UserUpdateForm]] } - implicit val columnToMapApibuilderApiUserUpdateForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.UserUpdateForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.UserUpdateForm]] } - implicit val columnToSeqApibuilderApiValidation: Column[Seq[_root_.io.apibuilder.api.v0.models.Validation]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Validation]] } - implicit val columnToMapApibuilderApiValidation: Column[Map[String, _root_.io.apibuilder.api.v0.models.Validation]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Validation]] } - implicit val columnToSeqApibuilderApiVersion: Column[Seq[_root_.io.apibuilder.api.v0.models.Version]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Version]] } - implicit val columnToMapApibuilderApiVersion: Column[Map[String, _root_.io.apibuilder.api.v0.models.Version]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Version]] } - implicit val columnToSeqApibuilderApiVersionForm: Column[Seq[_root_.io.apibuilder.api.v0.models.VersionForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.VersionForm]] } - implicit val columnToMapApibuilderApiVersionForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.VersionForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.VersionForm]] } - implicit val columnToSeqApibuilderApiWatch: Column[Seq[_root_.io.apibuilder.api.v0.models.Watch]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Watch]] } - implicit val columnToMapApibuilderApiWatch: Column[Map[String, _root_.io.apibuilder.api.v0.models.Watch]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Watch]] } - implicit val columnToSeqApibuilderApiWatchForm: Column[Seq[_root_.io.apibuilder.api.v0.models.WatchForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.WatchForm]] } - implicit val columnToMapApibuilderApiWatchForm: Column[Map[String, _root_.io.apibuilder.api.v0.models.WatchForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.WatchForm]] } - implicit val columnToSeqApibuilderApiDiff: Column[Seq[_root_.io.apibuilder.api.v0.models.Diff]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.Diff]] } - implicit val columnToMapApibuilderApiDiff: Column[Map[String, _root_.io.apibuilder.api.v0.models.Diff]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.Diff]] } - implicit val columnToSeqApibuilderApiItemDetail: Column[Seq[_root_.io.apibuilder.api.v0.models.ItemDetail]] = Util.parser { _.as[Seq[_root_.io.apibuilder.api.v0.models.ItemDetail]] } - implicit val columnToMapApibuilderApiItemDetail: Column[Map[String, _root_.io.apibuilder.api.v0.models.ItemDetail]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.api.v0.models.ItemDetail]] } } object Standard { - implicit val columnToJsObject: Column[play.api.libs.json.JsObject] = Util.parser { _.as[play.api.libs.json.JsObject] } implicit val columnToJsValue: Column[play.api.libs.json.JsValue] = Util.parser { _.as[play.api.libs.json.JsValue] } - implicit val columnToSeqBoolean: Column[Seq[Boolean]] = Util.parser { _.as[Seq[Boolean]] } - implicit val columnToMapBoolean: Column[Map[String, Boolean]] = Util.parser { _.as[Map[String, Boolean]] } - implicit val columnToSeqDouble: Column[Seq[Double]] = Util.parser { _.as[Seq[Double]] } - implicit val columnToMapDouble: Column[Map[String, Double]] = Util.parser { _.as[Map[String, Double]] } - implicit val columnToSeqInt: Column[Seq[Int]] = Util.parser { _.as[Seq[Int]] } - implicit val columnToMapInt: Column[Map[String, Int]] = Util.parser { _.as[Map[String, Int]] } - implicit val columnToSeqLong: Column[Seq[Long]] = Util.parser { _.as[Seq[Long]] } - implicit val columnToMapLong: Column[Map[String, Long]] = Util.parser { _.as[Map[String, Long]] } - implicit val columnToSeqLocalDate: Column[Seq[_root_.org.joda.time.LocalDate]] = Util.parser { _.as[Seq[_root_.org.joda.time.LocalDate]] } - implicit val columnToMapLocalDate: Column[Map[String, _root_.org.joda.time.LocalDate]] = Util.parser { _.as[Map[String, _root_.org.joda.time.LocalDate]] } - implicit val columnToSeqDateTime: Column[Seq[_root_.org.joda.time.DateTime]] = Util.parser { _.as[Seq[_root_.org.joda.time.DateTime]] } - implicit val columnToMapDateTime: Column[Map[String, _root_.org.joda.time.DateTime]] = Util.parser { _.as[Map[String, _root_.org.joda.time.DateTime]] } - implicit val columnToSeqBigDecimal: Column[Seq[BigDecimal]] = Util.parser { _.as[Seq[BigDecimal]] } - implicit val columnToMapBigDecimal: Column[Map[String, BigDecimal]] = Util.parser { _.as[Map[String, BigDecimal]] } - implicit val columnToSeqJsObject: Column[Seq[_root_.play.api.libs.json.JsObject]] = Util.parser { _.as[Seq[_root_.play.api.libs.json.JsObject]] } - implicit val columnToMapJsObject: Column[Map[String, _root_.play.api.libs.json.JsObject]] = Util.parser { _.as[Map[String, _root_.play.api.libs.json.JsObject]] } - implicit val columnToSeqJsValue: Column[Seq[_root_.play.api.libs.json.JsValue]] = Util.parser { _.as[Seq[_root_.play.api.libs.json.JsValue]] } - implicit val columnToMapJsValue: Column[Map[String, _root_.play.api.libs.json.JsValue]] = Util.parser { _.as[Map[String, _root_.play.api.libs.json.JsValue]] } - implicit val columnToSeqString: Column[Seq[String]] = Util.parser { _.as[Seq[String]] } - implicit val columnToMapString: Column[Map[String, String]] = Util.parser { _.as[Map[String, String]] } - implicit val columnToSeqUUID: Column[Seq[_root_.java.util.UUID]] = Util.parser { _.as[Seq[_root_.java.util.UUID]] } - implicit val columnToMapUUID: Column[Map[String, _root_.java.util.UUID]] = Util.parser { _.as[Map[String, _root_.java.util.UUID]] } } } \ No newline at end of file diff --git a/api/app/generated/ApicollectiveApibuilderCommonV0Conversions.scala b/api/app/generated/ApicollectiveApibuilderCommonV0Conversions.scala index 40053ac0c..e97bad5f5 100644 --- a/api/app/generated/ApicollectiveApibuilderCommonV0Conversions.scala +++ b/api/app/generated/ApicollectiveApibuilderCommonV0Conversions.scala @@ -1,14 +1,13 @@ /** * Generated by API Builder - https://www.apibuilder.io - * Service version: 0.16.43 - * apibuilder app.apibuilder.io/apicollective/apibuilder-common/latest/anorm_2_8_parsers + * Service version: 0.16.50 + * User agent: apibuilder localhost 9000/apicollective/apibuilder-common/latest/anorm_2_9_scala_3_parsers */ package io.apibuilder.common.v0.anorm.conversions { import anorm.{Column, MetaDataItem, TypeDoesNotMatch} import play.api.libs.json.{JsArray, JsObject, JsValue} import scala.util.{Failure, Success, Try} - import play.api.libs.json.JodaReads._ /** * Conversions to collections of objects using JSON. @@ -52,44 +51,10 @@ package io.apibuilder.common.v0.anorm.conversions { } object Types { - import io.apibuilder.common.v0.models.json._ - implicit val columnToSeqApibuilderCommonMembershipRole: Column[Seq[_root_.io.apibuilder.common.v0.models.MembershipRole]] = Util.parser { _.as[Seq[_root_.io.apibuilder.common.v0.models.MembershipRole]] } - implicit val columnToMapApibuilderCommonMembershipRole: Column[Map[String, _root_.io.apibuilder.common.v0.models.MembershipRole]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.common.v0.models.MembershipRole]] } - implicit val columnToSeqApibuilderCommonAudit: Column[Seq[_root_.io.apibuilder.common.v0.models.Audit]] = Util.parser { _.as[Seq[_root_.io.apibuilder.common.v0.models.Audit]] } - implicit val columnToMapApibuilderCommonAudit: Column[Map[String, _root_.io.apibuilder.common.v0.models.Audit]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.common.v0.models.Audit]] } - implicit val columnToSeqApibuilderCommonHealthcheck: Column[Seq[_root_.io.apibuilder.common.v0.models.Healthcheck]] = Util.parser { _.as[Seq[_root_.io.apibuilder.common.v0.models.Healthcheck]] } - implicit val columnToMapApibuilderCommonHealthcheck: Column[Map[String, _root_.io.apibuilder.common.v0.models.Healthcheck]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.common.v0.models.Healthcheck]] } - implicit val columnToSeqApibuilderCommonReference: Column[Seq[_root_.io.apibuilder.common.v0.models.Reference]] = Util.parser { _.as[Seq[_root_.io.apibuilder.common.v0.models.Reference]] } - implicit val columnToMapApibuilderCommonReference: Column[Map[String, _root_.io.apibuilder.common.v0.models.Reference]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.common.v0.models.Reference]] } - implicit val columnToSeqApibuilderCommonReferenceGuid: Column[Seq[_root_.io.apibuilder.common.v0.models.ReferenceGuid]] = Util.parser { _.as[Seq[_root_.io.apibuilder.common.v0.models.ReferenceGuid]] } - implicit val columnToMapApibuilderCommonReferenceGuid: Column[Map[String, _root_.io.apibuilder.common.v0.models.ReferenceGuid]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.common.v0.models.ReferenceGuid]] } } object Standard { - implicit val columnToJsObject: Column[play.api.libs.json.JsObject] = Util.parser { _.as[play.api.libs.json.JsObject] } implicit val columnToJsValue: Column[play.api.libs.json.JsValue] = Util.parser { _.as[play.api.libs.json.JsValue] } - implicit val columnToSeqBoolean: Column[Seq[Boolean]] = Util.parser { _.as[Seq[Boolean]] } - implicit val columnToMapBoolean: Column[Map[String, Boolean]] = Util.parser { _.as[Map[String, Boolean]] } - implicit val columnToSeqDouble: Column[Seq[Double]] = Util.parser { _.as[Seq[Double]] } - implicit val columnToMapDouble: Column[Map[String, Double]] = Util.parser { _.as[Map[String, Double]] } - implicit val columnToSeqInt: Column[Seq[Int]] = Util.parser { _.as[Seq[Int]] } - implicit val columnToMapInt: Column[Map[String, Int]] = Util.parser { _.as[Map[String, Int]] } - implicit val columnToSeqLong: Column[Seq[Long]] = Util.parser { _.as[Seq[Long]] } - implicit val columnToMapLong: Column[Map[String, Long]] = Util.parser { _.as[Map[String, Long]] } - implicit val columnToSeqLocalDate: Column[Seq[_root_.org.joda.time.LocalDate]] = Util.parser { _.as[Seq[_root_.org.joda.time.LocalDate]] } - implicit val columnToMapLocalDate: Column[Map[String, _root_.org.joda.time.LocalDate]] = Util.parser { _.as[Map[String, _root_.org.joda.time.LocalDate]] } - implicit val columnToSeqDateTime: Column[Seq[_root_.org.joda.time.DateTime]] = Util.parser { _.as[Seq[_root_.org.joda.time.DateTime]] } - implicit val columnToMapDateTime: Column[Map[String, _root_.org.joda.time.DateTime]] = Util.parser { _.as[Map[String, _root_.org.joda.time.DateTime]] } - implicit val columnToSeqBigDecimal: Column[Seq[BigDecimal]] = Util.parser { _.as[Seq[BigDecimal]] } - implicit val columnToMapBigDecimal: Column[Map[String, BigDecimal]] = Util.parser { _.as[Map[String, BigDecimal]] } - implicit val columnToSeqJsObject: Column[Seq[_root_.play.api.libs.json.JsObject]] = Util.parser { _.as[Seq[_root_.play.api.libs.json.JsObject]] } - implicit val columnToMapJsObject: Column[Map[String, _root_.play.api.libs.json.JsObject]] = Util.parser { _.as[Map[String, _root_.play.api.libs.json.JsObject]] } - implicit val columnToSeqJsValue: Column[Seq[_root_.play.api.libs.json.JsValue]] = Util.parser { _.as[Seq[_root_.play.api.libs.json.JsValue]] } - implicit val columnToMapJsValue: Column[Map[String, _root_.play.api.libs.json.JsValue]] = Util.parser { _.as[Map[String, _root_.play.api.libs.json.JsValue]] } - implicit val columnToSeqString: Column[Seq[String]] = Util.parser { _.as[Seq[String]] } - implicit val columnToMapString: Column[Map[String, String]] = Util.parser { _.as[Map[String, String]] } - implicit val columnToSeqUUID: Column[Seq[_root_.java.util.UUID]] = Util.parser { _.as[Seq[_root_.java.util.UUID]] } - implicit val columnToMapUUID: Column[Map[String, _root_.java.util.UUID]] = Util.parser { _.as[Map[String, _root_.java.util.UUID]] } } } \ No newline at end of file diff --git a/api/app/generated/ApicollectiveApibuilderGeneratorV0Conversions.scala b/api/app/generated/ApicollectiveApibuilderGeneratorV0Conversions.scala index b709545cc..7136b2bd4 100644 --- a/api/app/generated/ApicollectiveApibuilderGeneratorV0Conversions.scala +++ b/api/app/generated/ApicollectiveApibuilderGeneratorV0Conversions.scala @@ -1,14 +1,13 @@ /** * Generated by API Builder - https://www.apibuilder.io - * Service version: 0.16.43 - * apibuilder app.apibuilder.io/apicollective/apibuilder-generator/latest/anorm_2_8_parsers + * Service version: 0.16.50 + * User agent: apibuilder localhost 9000/apicollective/apibuilder-generator/latest/anorm_2_9_scala_3_parsers */ package io.apibuilder.generator.v0.anorm.conversions { import anorm.{Column, MetaDataItem, TypeDoesNotMatch} import play.api.libs.json.{JsArray, JsObject, JsValue} import scala.util.{Failure, Success, Try} - import play.api.libs.json.JodaReads._ /** * Conversions to collections of objects using JSON. @@ -52,50 +51,10 @@ package io.apibuilder.generator.v0.anorm.conversions { } object Types { - import io.apibuilder.generator.v0.models.json._ - implicit val columnToSeqApibuilderGeneratorFileFlag: Column[Seq[_root_.io.apibuilder.generator.v0.models.FileFlag]] = Util.parser { _.as[Seq[_root_.io.apibuilder.generator.v0.models.FileFlag]] } - implicit val columnToMapApibuilderGeneratorFileFlag: Column[Map[String, _root_.io.apibuilder.generator.v0.models.FileFlag]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.generator.v0.models.FileFlag]] } - implicit val columnToSeqApibuilderGeneratorAttribute: Column[Seq[_root_.io.apibuilder.generator.v0.models.Attribute]] = Util.parser { _.as[Seq[_root_.io.apibuilder.generator.v0.models.Attribute]] } - implicit val columnToMapApibuilderGeneratorAttribute: Column[Map[String, _root_.io.apibuilder.generator.v0.models.Attribute]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.generator.v0.models.Attribute]] } - implicit val columnToSeqApibuilderGeneratorError: Column[Seq[_root_.io.apibuilder.generator.v0.models.Error]] = Util.parser { _.as[Seq[_root_.io.apibuilder.generator.v0.models.Error]] } - implicit val columnToMapApibuilderGeneratorError: Column[Map[String, _root_.io.apibuilder.generator.v0.models.Error]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.generator.v0.models.Error]] } - implicit val columnToSeqApibuilderGeneratorFile: Column[Seq[_root_.io.apibuilder.generator.v0.models.File]] = Util.parser { _.as[Seq[_root_.io.apibuilder.generator.v0.models.File]] } - implicit val columnToMapApibuilderGeneratorFile: Column[Map[String, _root_.io.apibuilder.generator.v0.models.File]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.generator.v0.models.File]] } - implicit val columnToSeqApibuilderGeneratorGenerator: Column[Seq[_root_.io.apibuilder.generator.v0.models.Generator]] = Util.parser { _.as[Seq[_root_.io.apibuilder.generator.v0.models.Generator]] } - implicit val columnToMapApibuilderGeneratorGenerator: Column[Map[String, _root_.io.apibuilder.generator.v0.models.Generator]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.generator.v0.models.Generator]] } - implicit val columnToSeqApibuilderGeneratorHealthcheck: Column[Seq[_root_.io.apibuilder.generator.v0.models.Healthcheck]] = Util.parser { _.as[Seq[_root_.io.apibuilder.generator.v0.models.Healthcheck]] } - implicit val columnToMapApibuilderGeneratorHealthcheck: Column[Map[String, _root_.io.apibuilder.generator.v0.models.Healthcheck]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.generator.v0.models.Healthcheck]] } - implicit val columnToSeqApibuilderGeneratorInvocation: Column[Seq[_root_.io.apibuilder.generator.v0.models.Invocation]] = Util.parser { _.as[Seq[_root_.io.apibuilder.generator.v0.models.Invocation]] } - implicit val columnToMapApibuilderGeneratorInvocation: Column[Map[String, _root_.io.apibuilder.generator.v0.models.Invocation]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.generator.v0.models.Invocation]] } - implicit val columnToSeqApibuilderGeneratorInvocationForm: Column[Seq[_root_.io.apibuilder.generator.v0.models.InvocationForm]] = Util.parser { _.as[Seq[_root_.io.apibuilder.generator.v0.models.InvocationForm]] } - implicit val columnToMapApibuilderGeneratorInvocationForm: Column[Map[String, _root_.io.apibuilder.generator.v0.models.InvocationForm]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.generator.v0.models.InvocationForm]] } } object Standard { - implicit val columnToJsObject: Column[play.api.libs.json.JsObject] = Util.parser { _.as[play.api.libs.json.JsObject] } implicit val columnToJsValue: Column[play.api.libs.json.JsValue] = Util.parser { _.as[play.api.libs.json.JsValue] } - implicit val columnToSeqBoolean: Column[Seq[Boolean]] = Util.parser { _.as[Seq[Boolean]] } - implicit val columnToMapBoolean: Column[Map[String, Boolean]] = Util.parser { _.as[Map[String, Boolean]] } - implicit val columnToSeqDouble: Column[Seq[Double]] = Util.parser { _.as[Seq[Double]] } - implicit val columnToMapDouble: Column[Map[String, Double]] = Util.parser { _.as[Map[String, Double]] } - implicit val columnToSeqInt: Column[Seq[Int]] = Util.parser { _.as[Seq[Int]] } - implicit val columnToMapInt: Column[Map[String, Int]] = Util.parser { _.as[Map[String, Int]] } - implicit val columnToSeqLong: Column[Seq[Long]] = Util.parser { _.as[Seq[Long]] } - implicit val columnToMapLong: Column[Map[String, Long]] = Util.parser { _.as[Map[String, Long]] } - implicit val columnToSeqLocalDate: Column[Seq[_root_.org.joda.time.LocalDate]] = Util.parser { _.as[Seq[_root_.org.joda.time.LocalDate]] } - implicit val columnToMapLocalDate: Column[Map[String, _root_.org.joda.time.LocalDate]] = Util.parser { _.as[Map[String, _root_.org.joda.time.LocalDate]] } - implicit val columnToSeqDateTime: Column[Seq[_root_.org.joda.time.DateTime]] = Util.parser { _.as[Seq[_root_.org.joda.time.DateTime]] } - implicit val columnToMapDateTime: Column[Map[String, _root_.org.joda.time.DateTime]] = Util.parser { _.as[Map[String, _root_.org.joda.time.DateTime]] } - implicit val columnToSeqBigDecimal: Column[Seq[BigDecimal]] = Util.parser { _.as[Seq[BigDecimal]] } - implicit val columnToMapBigDecimal: Column[Map[String, BigDecimal]] = Util.parser { _.as[Map[String, BigDecimal]] } - implicit val columnToSeqJsObject: Column[Seq[_root_.play.api.libs.json.JsObject]] = Util.parser { _.as[Seq[_root_.play.api.libs.json.JsObject]] } - implicit val columnToMapJsObject: Column[Map[String, _root_.play.api.libs.json.JsObject]] = Util.parser { _.as[Map[String, _root_.play.api.libs.json.JsObject]] } - implicit val columnToSeqJsValue: Column[Seq[_root_.play.api.libs.json.JsValue]] = Util.parser { _.as[Seq[_root_.play.api.libs.json.JsValue]] } - implicit val columnToMapJsValue: Column[Map[String, _root_.play.api.libs.json.JsValue]] = Util.parser { _.as[Map[String, _root_.play.api.libs.json.JsValue]] } - implicit val columnToSeqString: Column[Seq[String]] = Util.parser { _.as[Seq[String]] } - implicit val columnToMapString: Column[Map[String, String]] = Util.parser { _.as[Map[String, String]] } - implicit val columnToSeqUUID: Column[Seq[_root_.java.util.UUID]] = Util.parser { _.as[Seq[_root_.java.util.UUID]] } - implicit val columnToMapUUID: Column[Map[String, _root_.java.util.UUID]] = Util.parser { _.as[Map[String, _root_.java.util.UUID]] } } } \ No newline at end of file diff --git a/api/app/generated/ApicollectiveApibuilderSpecV0Conversions.scala b/api/app/generated/ApicollectiveApibuilderSpecV0Conversions.scala index 6133e9860..cf084805a 100644 --- a/api/app/generated/ApicollectiveApibuilderSpecV0Conversions.scala +++ b/api/app/generated/ApicollectiveApibuilderSpecV0Conversions.scala @@ -1,14 +1,13 @@ /** * Generated by API Builder - https://www.apibuilder.io - * Service version: 0.16.43 - * apibuilder app.apibuilder.io/apicollective/apibuilder-spec/latest/anorm_2_8_parsers + * Service version: 0.16.50 + * User agent: apibuilder localhost 9000/apicollective/apibuilder-spec/latest/anorm_2_9_scala_3_parsers */ package io.apibuilder.spec.v0.anorm.conversions { import anorm.{Column, MetaDataItem, TypeDoesNotMatch} import play.api.libs.json.{JsArray, JsObject, JsValue} import scala.util.{Failure, Success, Try} - import play.api.libs.json.JodaReads._ /** * Conversions to collections of objects using JSON. @@ -52,90 +51,10 @@ package io.apibuilder.spec.v0.anorm.conversions { } object Types { - import io.apibuilder.spec.v0.models.json._ - implicit val columnToSeqApibuilderSpecMethod: Column[Seq[_root_.io.apibuilder.spec.v0.models.Method]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Method]] } - implicit val columnToMapApibuilderSpecMethod: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Method]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Method]] } - implicit val columnToSeqApibuilderSpecParameterLocation: Column[Seq[_root_.io.apibuilder.spec.v0.models.ParameterLocation]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.ParameterLocation]] } - implicit val columnToMapApibuilderSpecParameterLocation: Column[Map[String, _root_.io.apibuilder.spec.v0.models.ParameterLocation]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.ParameterLocation]] } - implicit val columnToSeqApibuilderSpecResponseCodeOption: Column[Seq[_root_.io.apibuilder.spec.v0.models.ResponseCodeOption]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.ResponseCodeOption]] } - implicit val columnToMapApibuilderSpecResponseCodeOption: Column[Map[String, _root_.io.apibuilder.spec.v0.models.ResponseCodeOption]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.ResponseCodeOption]] } - implicit val columnToSeqApibuilderSpecAnnotation: Column[Seq[_root_.io.apibuilder.spec.v0.models.Annotation]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Annotation]] } - implicit val columnToMapApibuilderSpecAnnotation: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Annotation]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Annotation]] } - implicit val columnToSeqApibuilderSpecApidoc: Column[Seq[_root_.io.apibuilder.spec.v0.models.Apidoc]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Apidoc]] } - implicit val columnToMapApibuilderSpecApidoc: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Apidoc]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Apidoc]] } - implicit val columnToSeqApibuilderSpecApplication: Column[Seq[_root_.io.apibuilder.spec.v0.models.Application]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Application]] } - implicit val columnToMapApibuilderSpecApplication: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Application]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Application]] } - implicit val columnToSeqApibuilderSpecAttribute: Column[Seq[_root_.io.apibuilder.spec.v0.models.Attribute]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Attribute]] } - implicit val columnToMapApibuilderSpecAttribute: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Attribute]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Attribute]] } - implicit val columnToSeqApibuilderSpecBody: Column[Seq[_root_.io.apibuilder.spec.v0.models.Body]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Body]] } - implicit val columnToMapApibuilderSpecBody: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Body]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Body]] } - implicit val columnToSeqApibuilderSpecContact: Column[Seq[_root_.io.apibuilder.spec.v0.models.Contact]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Contact]] } - implicit val columnToMapApibuilderSpecContact: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Contact]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Contact]] } - implicit val columnToSeqApibuilderSpecDeprecation: Column[Seq[_root_.io.apibuilder.spec.v0.models.Deprecation]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Deprecation]] } - implicit val columnToMapApibuilderSpecDeprecation: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Deprecation]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Deprecation]] } - implicit val columnToSeqApibuilderSpecEnum: Column[Seq[_root_.io.apibuilder.spec.v0.models.Enum]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Enum]] } - implicit val columnToMapApibuilderSpecEnum: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Enum]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Enum]] } - implicit val columnToSeqApibuilderSpecEnumValue: Column[Seq[_root_.io.apibuilder.spec.v0.models.EnumValue]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.EnumValue]] } - implicit val columnToMapApibuilderSpecEnumValue: Column[Map[String, _root_.io.apibuilder.spec.v0.models.EnumValue]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.EnumValue]] } - implicit val columnToSeqApibuilderSpecField: Column[Seq[_root_.io.apibuilder.spec.v0.models.Field]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Field]] } - implicit val columnToMapApibuilderSpecField: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Field]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Field]] } - implicit val columnToSeqApibuilderSpecHeader: Column[Seq[_root_.io.apibuilder.spec.v0.models.Header]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Header]] } - implicit val columnToMapApibuilderSpecHeader: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Header]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Header]] } - implicit val columnToSeqApibuilderSpecImport: Column[Seq[_root_.io.apibuilder.spec.v0.models.Import]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Import]] } - implicit val columnToMapApibuilderSpecImport: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Import]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Import]] } - implicit val columnToSeqApibuilderSpecInfo: Column[Seq[_root_.io.apibuilder.spec.v0.models.Info]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Info]] } - implicit val columnToMapApibuilderSpecInfo: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Info]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Info]] } - implicit val columnToSeqApibuilderSpecInterface: Column[Seq[_root_.io.apibuilder.spec.v0.models.Interface]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Interface]] } - implicit val columnToMapApibuilderSpecInterface: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Interface]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Interface]] } - implicit val columnToSeqApibuilderSpecLicense: Column[Seq[_root_.io.apibuilder.spec.v0.models.License]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.License]] } - implicit val columnToMapApibuilderSpecLicense: Column[Map[String, _root_.io.apibuilder.spec.v0.models.License]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.License]] } - implicit val columnToSeqApibuilderSpecModel: Column[Seq[_root_.io.apibuilder.spec.v0.models.Model]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Model]] } - implicit val columnToMapApibuilderSpecModel: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Model]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Model]] } - implicit val columnToSeqApibuilderSpecOperation: Column[Seq[_root_.io.apibuilder.spec.v0.models.Operation]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Operation]] } - implicit val columnToMapApibuilderSpecOperation: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Operation]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Operation]] } - implicit val columnToSeqApibuilderSpecOrganization: Column[Seq[_root_.io.apibuilder.spec.v0.models.Organization]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Organization]] } - implicit val columnToMapApibuilderSpecOrganization: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Organization]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Organization]] } - implicit val columnToSeqApibuilderSpecParameter: Column[Seq[_root_.io.apibuilder.spec.v0.models.Parameter]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Parameter]] } - implicit val columnToMapApibuilderSpecParameter: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Parameter]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Parameter]] } - implicit val columnToSeqApibuilderSpecResource: Column[Seq[_root_.io.apibuilder.spec.v0.models.Resource]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Resource]] } - implicit val columnToMapApibuilderSpecResource: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Resource]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Resource]] } - implicit val columnToSeqApibuilderSpecResponse: Column[Seq[_root_.io.apibuilder.spec.v0.models.Response]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Response]] } - implicit val columnToMapApibuilderSpecResponse: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Response]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Response]] } - implicit val columnToSeqApibuilderSpecService: Column[Seq[_root_.io.apibuilder.spec.v0.models.Service]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Service]] } - implicit val columnToMapApibuilderSpecService: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Service]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Service]] } - implicit val columnToSeqApibuilderSpecUnion: Column[Seq[_root_.io.apibuilder.spec.v0.models.Union]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.Union]] } - implicit val columnToMapApibuilderSpecUnion: Column[Map[String, _root_.io.apibuilder.spec.v0.models.Union]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.Union]] } - implicit val columnToSeqApibuilderSpecUnionType: Column[Seq[_root_.io.apibuilder.spec.v0.models.UnionType]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.UnionType]] } - implicit val columnToMapApibuilderSpecUnionType: Column[Map[String, _root_.io.apibuilder.spec.v0.models.UnionType]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.UnionType]] } - implicit val columnToSeqApibuilderSpecResponseCode: Column[Seq[_root_.io.apibuilder.spec.v0.models.ResponseCode]] = Util.parser { _.as[Seq[_root_.io.apibuilder.spec.v0.models.ResponseCode]] } - implicit val columnToMapApibuilderSpecResponseCode: Column[Map[String, _root_.io.apibuilder.spec.v0.models.ResponseCode]] = Util.parser { _.as[Map[String, _root_.io.apibuilder.spec.v0.models.ResponseCode]] } } object Standard { - implicit val columnToJsObject: Column[play.api.libs.json.JsObject] = Util.parser { _.as[play.api.libs.json.JsObject] } implicit val columnToJsValue: Column[play.api.libs.json.JsValue] = Util.parser { _.as[play.api.libs.json.JsValue] } - implicit val columnToSeqBoolean: Column[Seq[Boolean]] = Util.parser { _.as[Seq[Boolean]] } - implicit val columnToMapBoolean: Column[Map[String, Boolean]] = Util.parser { _.as[Map[String, Boolean]] } - implicit val columnToSeqDouble: Column[Seq[Double]] = Util.parser { _.as[Seq[Double]] } - implicit val columnToMapDouble: Column[Map[String, Double]] = Util.parser { _.as[Map[String, Double]] } - implicit val columnToSeqInt: Column[Seq[Int]] = Util.parser { _.as[Seq[Int]] } - implicit val columnToMapInt: Column[Map[String, Int]] = Util.parser { _.as[Map[String, Int]] } - implicit val columnToSeqLong: Column[Seq[Long]] = Util.parser { _.as[Seq[Long]] } - implicit val columnToMapLong: Column[Map[String, Long]] = Util.parser { _.as[Map[String, Long]] } - implicit val columnToSeqLocalDate: Column[Seq[_root_.org.joda.time.LocalDate]] = Util.parser { _.as[Seq[_root_.org.joda.time.LocalDate]] } - implicit val columnToMapLocalDate: Column[Map[String, _root_.org.joda.time.LocalDate]] = Util.parser { _.as[Map[String, _root_.org.joda.time.LocalDate]] } - implicit val columnToSeqDateTime: Column[Seq[_root_.org.joda.time.DateTime]] = Util.parser { _.as[Seq[_root_.org.joda.time.DateTime]] } - implicit val columnToMapDateTime: Column[Map[String, _root_.org.joda.time.DateTime]] = Util.parser { _.as[Map[String, _root_.org.joda.time.DateTime]] } - implicit val columnToSeqBigDecimal: Column[Seq[BigDecimal]] = Util.parser { _.as[Seq[BigDecimal]] } - implicit val columnToMapBigDecimal: Column[Map[String, BigDecimal]] = Util.parser { _.as[Map[String, BigDecimal]] } - implicit val columnToSeqJsObject: Column[Seq[_root_.play.api.libs.json.JsObject]] = Util.parser { _.as[Seq[_root_.play.api.libs.json.JsObject]] } - implicit val columnToMapJsObject: Column[Map[String, _root_.play.api.libs.json.JsObject]] = Util.parser { _.as[Map[String, _root_.play.api.libs.json.JsObject]] } - implicit val columnToSeqJsValue: Column[Seq[_root_.play.api.libs.json.JsValue]] = Util.parser { _.as[Seq[_root_.play.api.libs.json.JsValue]] } - implicit val columnToMapJsValue: Column[Map[String, _root_.play.api.libs.json.JsValue]] = Util.parser { _.as[Map[String, _root_.play.api.libs.json.JsValue]] } - implicit val columnToSeqString: Column[Seq[String]] = Util.parser { _.as[Seq[String]] } - implicit val columnToMapString: Column[Map[String, String]] = Util.parser { _.as[Map[String, String]] } - implicit val columnToSeqUUID: Column[Seq[_root_.java.util.UUID]] = Util.parser { _.as[Seq[_root_.java.util.UUID]] } - implicit val columnToMapUUID: Column[Map[String, _root_.java.util.UUID]] = Util.parser { _.as[Map[String, _root_.java.util.UUID]] } } } \ No newline at end of file diff --git a/api/app/lib/AppConfig.scala b/api/app/lib/AppConfig.scala index 4de9228cd..818d1b7e3 100644 --- a/api/app/lib/AppConfig.scala +++ b/api/app/lib/AppConfig.scala @@ -2,6 +2,9 @@ package lib import javax.inject.{Inject, Singleton} +case class RollbarConfig(enabled: Boolean, accessToken: String) +case class SendgridConfig(apiKey: String) + @Singleton class AppConfig @Inject() ( config: Config @@ -21,5 +24,18 @@ class AppConfig @Inject() ( /** * optional as only used in production environment */ - val sendgridApiKey: Option[String] = config.optionalString("sendgrid.apiKey") + val sendgridConfig: Option[SendgridConfig] = config.optionalString("sendgrid.apiKey").map { key => + SendgridConfig(apiKey = key) + } + + val rollbarConfig: RollbarConfig = { + val enabled = config.optionalBoolean("rollbar.enabled").getOrElse(false) + RollbarConfig( + enabled = enabled, + accessToken = config.optionalString("rollbar.access.token").getOrElse { + assert(!enabled, "rollbar.access.token is required when rollbar is enabled") + "development" + } + ) + } } diff --git a/api/app/lib/Config.scala b/api/app/lib/Config.scala index b8c190513..13c1d4686 100644 --- a/api/app/lib/Config.scala +++ b/api/app/lib/Config.scala @@ -35,4 +35,16 @@ class Config @Inject() ( } } } + + def optionalBoolean(name: String): Option[Boolean] = { + optionalString(name).map(_.trim.toLowerCase()).map { + case "true" => true + case "false" => false + case other => { + val msg = s"Value for configuration parameter[$name], if specified, must be 'true' or 'false' and not '$other'" + logger.error(msg) + sys.error(msg) + } + } + } } diff --git a/api/app/lib/EmailUtil.scala b/api/app/lib/EmailUtil.scala index 073acf760..b4b65b7e4 100644 --- a/api/app/lib/EmailUtil.scala +++ b/api/app/lib/EmailUtil.scala @@ -38,10 +38,10 @@ class EmailUtil @Inject()( // string. private val sendgrid = { localDeliveryDir match { - case None => new SendGrid(appConfig.sendgridApiKey.getOrElse { - sys.error(s"sendgridApiKey required when localDeliveryDir is not set") - }) - case Some(_) => new SendGrid(appConfig.sendgridApiKey.getOrElse("development")) + case None => new SendGrid(appConfig.sendgridConfig.getOrElse { + sys.error(s"sendgridConfig required when localDeliveryDir is not set") + }.apiKey) + case Some(_) => new SendGrid(appConfig.sendgridConfig.map(_.apiKey).getOrElse("development")) } } diff --git a/api/app/lib/ExampleJson.scala b/api/app/lib/ExampleJson.scala index be1582ec8..39403c3a4 100644 --- a/api/app/lib/ExampleJson.scala +++ b/api/app/lib/ExampleJson.scala @@ -67,7 +67,7 @@ case class ExampleJson(service: Service, selection: Selection) { filter { f => selection == Selection.All || f.required }. map { field => (field.name, mockValue(field, typeAcc)) - }: _* + }* ) ) diff --git a/api/app/lib/ServiceDiff.scala b/api/app/lib/ServiceDiff.scala index b4ce00ad8..a300d0a4d 100644 --- a/api/app/lib/ServiceDiff.scala +++ b/api/app/lib/ServiceDiff.scala @@ -708,8 +708,8 @@ case class ServiceDiff( } def diffAttributes(prefix: String, a: Seq[Attribute], b: Seq[Attribute]): Seq[Diff] = { - val aMap = Map(a map ( attr => attr.name -> attr ): _*) - val bMap = Map(b map ( attr => attr.name -> attr ): _*) + val aMap = Map(a map ( attr => attr.name -> attr )*) + val bMap = Map(b map ( attr => attr.name -> attr )*) val aNames = aMap.keys.toSeq val bNames = bMap.keys.toSeq diff --git a/api/app/logger/ApiBuilderLogger.scala b/api/app/logger/ApiBuilderLogger.scala new file mode 100644 index 000000000..cd57f8669 --- /dev/null +++ b/api/app/logger/ApiBuilderLogger.scala @@ -0,0 +1,172 @@ +package logger + +import cats.data.NonEmptyChain +import com.rollbar.notifier.Rollbar +import com.rollbar.notifier.config.ConfigBuilder +import lib.AppConfig +import org.slf4j.{Logger, LoggerFactory} +import play.api.{Environment, Mode} + +import java.util +import javax.inject.Inject +import scala.jdk.CollectionConverters._ + +trait CommonLogger { + def withKeyValue(name: String, value: String): CommonLogger + def withKeyValues(name: String, values: Seq[String], max: Int = 10): CommonLogger + + def info(msg: String): Unit + def warn(msg: String): Unit + def warn(ex: Throwable, msg: String): Unit + def error(msg: String): Unit + def error(ex: Throwable, msg: String): Unit + + final def withKeyValue(name: String, value: Boolean): CommonLogger = withKeyValue(name, value.toString) + final def withKeyValue(name: String, value: Int): CommonLogger = withKeyValue(name, value.toString) + final def withKeyValue(name: String, value: Long): CommonLogger = withKeyValue(name, value.toString) + final def withKeyValue(name: String, value: BigDecimal): CommonLogger = withKeyValue(name, value.toString) + final def withKeyValue(name: String, value: Option[String]): CommonLogger = { + value match { + case None => this + case Some(v) => withKeyValue(name, v) + } + } + + final def withKeyValues(name: String, values: NonEmptyChain[String]): CommonLogger = { + withKeyValues(name, values.toNonEmptyList.toList) + } + + final def organization(key: String): CommonLogger = { + withKeyValue("organization_key", key) + } +} + +class ApiBuilderLogger @Inject() ( + env: Environment, + appConfig: AppConfig +) extends CommonLogger { + + private lazy val logger = LoggerFactory.getLogger("application") + + private lazy val rollbar: Rollbar = { + val config = ConfigBuilder + .withAccessToken(appConfig.rollbarConfig.accessToken) + .environment(env.mode.toString) + .build + Rollbar.init(config) + } + + private def builder: CommonLogger = AcumenLoggerBuilder( + mode = env.mode, + logger = logger, + rollbar = rollbar, + enableRollbar = appConfig.rollbarConfig.enabled + ).withKeyValue("environment", env.mode.toString) + + override def withKeyValue(name: String, value: String): CommonLogger = { + builder.withKeyValue(name, value) + } + + override def withKeyValues(name: String, values: Seq[String], max: Int = 10): CommonLogger = { + builder.withKeyValues(name, values.take(max)) + } + + override def info(msg: String): Unit = builder.info(msg) + override def warn(msg: String): Unit = builder.warn(msg) + override def warn(ex: Throwable, msg: String): Unit = builder.warn(ex, msg) + override def error(msg: String): Unit = builder.warn(msg) + override def error(ex: Throwable, msg: String): Unit = builder.warn(ex, msg) + +} + +case class AcumenLoggerBuilder( + mode: Mode, + logger: Logger, + rollbar: Rollbar, + enableRollbar: Boolean, + keyValues: Map[String, String] = Map.empty +) extends CommonLogger { + + override def withKeyValue(name: String, value: String): AcumenLoggerBuilder = { + this.copy( + keyValues = keyValues ++ Map(name -> value) + ) + } + + override def withKeyValues(name: String, values: Seq[String], max: Int = 10): AcumenLoggerBuilder = { + values.toList match { + case one :: Nil => withKeyValue(name, one) + case _ => + this.copy( + keyValues = keyValues ++ values.take(max).zipWithIndex.map { case (v, i) => (s"${name}_${i}", v) } + ) + } + } + + override def info(msg: String): Unit = { + logger.info(build(msg, None)) + } + + override def warn(msg: String): Unit = { + logger.warn(build(msg, None)) + ifRollbar { + rollbar.warning(msg, keyValuesToJava) + } + } + override def warn(ex: Throwable, msg: String): Unit = { + logger.warn(build(msg, Some(ex)), ex) + ifRollbar { + rollbar.warning(ex, keyValuesToJava, msg) + } + } + + override def error(msg: String): Unit = { + logger.error(build(msg, None)) + ifRollbar { + rollbar.error(msg, keyValuesToJava) + } + } + + override def error(ex: Throwable, msg: String): Unit = { + logger.error(build(msg, Some(ex)), ex) + ifRollbar { + rollbar.error(ex, keyValuesToJava, msg) + } + } + + private def ifRollbar(function: => Any): Unit = { + mode match { + case Mode.Prod if enableRollbar => { + function + () + } + case _ => // no-op + } + } + + private def keyValuesObjects: Map[String, Object] = keyValues + private def keyValuesToJava: util.Map[String, Object] = keyValuesObjects.asJava + + private def build(msg: String, ex: Option[Throwable]): String = { + val exMsg = ex match { + case None => "" + case Some(e) => { + e.printStackTrace(System.err) + s" ${e.getMessage}" + } + } + val sb = new StringBuilder() + sb.append(s"$msg$exMsg") + if (keyValues.nonEmpty) { + sb.append(" ") + sb.append( + keyValues.keys.toList.sorted + .map { k => + s"$k: ${keyValues(k)}" + } + .mkString(", ") + ) + } + sb.toString() + } +} diff --git a/api/app/processor/PurgeDeletedProcessor.scala b/api/app/processor/PurgeDeletedProcessor.scala index 35717c430..bf38ebd22 100644 --- a/api/app/processor/PurgeDeletedProcessor.scala +++ b/api/app/processor/PurgeDeletedProcessor.scala @@ -58,7 +58,7 @@ class PurgeDeletedProcessor @Inject()( } @tailrec - private def deleteAll(table: Table)(f: DbRow[_] => Any): Unit = { + private def deleteAll(table: Table)(f: DbRow[?] => Any): Unit = { val all = nextDeletedRows(table) if (all.nonEmpty) { all.foreach { row => @@ -73,7 +73,7 @@ class PurgeDeletedProcessor @Inject()( private val Limit = 1000 private case class DbRow[T](pkey: T, deletedAt: DateTime) - private def nextDeletedRows(table: Table): Seq[DbRow[_]] = { + private def nextDeletedRows(table: Table): Seq[DbRow[?]] = { db.withConnection { c => Query( s"select ${table.pkey.name}::text as pkey, deleted_at from ${table.qualified}" @@ -83,7 +83,7 @@ class PurgeDeletedProcessor @Inject()( } } - private def parser(primaryKey: PrimaryKey): RowParser[DbRow[_]] = { + private def parser(primaryKey: PrimaryKey): RowParser[DbRow[?]] = { import PrimaryKey._ SqlParser.get[String]("pkey") ~ SqlParser.get[DateTime]("deleted_at") map { diff --git a/api/app/util/ApiBuilderServiceImportResolver.scala b/api/app/util/ApiBuilderServiceImportResolver.scala index 36816de7c..4b0908c92 100644 --- a/api/app/util/ApiBuilderServiceImportResolver.scala +++ b/api/app/util/ApiBuilderServiceImportResolver.scala @@ -3,20 +3,18 @@ package util import db.{Authorization, VersionsDao} import io.apibuilder.api.v0.models.Version import io.apibuilder.spec.v0.models.{Import, Service} -import io.flow.log.RollbarLogger - -import javax.inject.Inject import lib.VersionTag +import logger.ApiBuilderLogger import models.VersionsModel +import javax.inject.Inject import scala.annotation.tailrec class ApiBuilderServiceImportResolver @Inject()( versionsDao: VersionsDao, - versionModel: VersionsModel, - rollbarLogger: RollbarLogger, + logger: ApiBuilderLogger, + versionModel: VersionsModel ) { - private val logger = rollbarLogger.fingerprint(getClass.getName) /** * Expands each import into its service definition, returning the list of imported services. diff --git a/api/conf/application.production.conf b/api/conf/application.production.conf index 3160b9190..0a189414e 100644 --- a/api/conf/application.production.conf +++ b/api/conf/application.production.conf @@ -11,3 +11,5 @@ play.modules.enabled += "modules.ProductionClientModule" sendgrid.apiKey=${?CONF_SENDGRID_API_KEY} +rollbar.accessToken=${?CONF_ROLLBAR_ACCESS_TOKEN} +rollbar.enabled=false diff --git a/api/conf/base.conf b/api/conf/base.conf index 45f925dd1..fa39d8331 100644 --- a/api/conf/base.conf +++ b/api/conf/base.conf @@ -17,7 +17,6 @@ play.http.parser.maxMemoryBuffer=10M play.http.requestHandler = "play.http.DefaultHttpRequestHandler" play.modules.enabled += "actors.ActorsModule" -play.modules.enabled += "io.flow.play.clients.ConfigModule" mail.defaultFromEmail="mbryzek@gmail.com" mail.defaultFromName="apibuilder" diff --git a/api/test/controllers/ApplicationMetadataSpec.scala b/api/test/controllers/ApplicationMetadataSpec.scala index f2b9a222b..8d73e05c5 100644 --- a/api/test/controllers/ApplicationMetadataSpec.scala +++ b/api/test/controllers/ApplicationMetadataSpec.scala @@ -36,6 +36,6 @@ class ApplicationMetadataSpec extends PlaySpec with MockClient with GuiceOneServ ).get() ) result.status must equal(200) - result.body must equal("2.0.0") + result.bodyAsBytes.utf8String must equal("2.0.0") } } diff --git a/api/test/db/MembershipRequestsDaoSpec.scala b/api/test/db/MembershipRequestsDaoSpec.scala index 5f491b314..97a9c913e 100644 --- a/api/test/db/MembershipRequestsDaoSpec.scala +++ b/api/test/db/MembershipRequestsDaoSpec.scala @@ -12,7 +12,7 @@ class MembershipRequestsDaoSpec extends PlaySpec with GuiceOneAppPerSuite with d private lazy val org: Organization = createOrganization() private lazy val member: User = upsertUser("gilt-member@bryzek.com") - private[this] def membershipRequestsModel: MembershipRequestsModel = app.injector.instanceOf[MembershipRequestsModel] + private def membershipRequestsModel: MembershipRequestsModel = app.injector.instanceOf[MembershipRequestsModel] "create member" in { val thisOrg = createOrganization() diff --git a/api/test/db/UserPasswordsDaoSpec.scala b/api/test/db/UserPasswordsDaoSpec.scala index 249a7436c..190f7e216 100644 --- a/api/test/db/UserPasswordsDaoSpec.scala +++ b/api/test/db/UserPasswordsDaoSpec.scala @@ -1,5 +1,6 @@ package db +import com.mbryzek.cipher.Ciphers import org.scalatestplus.play.PlaySpec import org.scalatestplus.play.guice.GuiceOneAppPerSuite @@ -7,17 +8,12 @@ class UserPasswordsDaoSpec extends PlaySpec with GuiceOneAppPerSuite with db.Hel private lazy val user = upsertUser("michael@mailinator.com") - "have distinct keys for all algorithms" in { - val keys = PasswordAlgorithm.All.map(_.key.toLowerCase) - keys must equal(keys.distinct.sorted) - } - "findByUserGuid" in { userPasswordsDao.create(user, user.guid, "password") val up = userPasswordsDao.findByUserGuid(user.guid).get up.userGuid must equal(user.guid) - up.algorithm must equal(PasswordAlgorithm.Latest) + up.algorithmKey must equal(Ciphers().latest.key) } "validate matching passwords" in { @@ -37,13 +33,7 @@ class UserPasswordsDaoSpec extends PlaySpec with GuiceOneAppPerSuite with db.Hel "hash the password" in { userPasswordsDao.create(user, user.guid, "password") val up = userPasswordsDao.findByUserGuid(user.guid).get - -1 must equal(up.hash.indexOf("password")) - } - - "generates unique hashes, even for same password" in { - PasswordAlgorithm.All.filter { _ != PasswordAlgorithm.Unknown }.foreach { algo => - algo.hash("password") != algo.hash("password") must be(true) - } + -1 must equal(up.base64EncodedHash.indexOf("password")) } } diff --git a/api/test/db/VersionsDaoSpec.scala b/api/test/db/VersionsDaoSpec.scala index e0ac9a75f..5cedb7057 100644 --- a/api/test/db/VersionsDaoSpec.scala +++ b/api/test/db/VersionsDaoSpec.scala @@ -28,9 +28,9 @@ class VersionsDaoSpec extends PlaySpec with GuiceOneAppPerSuite with db.Helpers "findByApplicationAndVersion" in { versionsDao.create(testUser, application, "1.0.1", Original, service) - val versionOpt = versionsDao.findByApplicationAndVersion(Authorization.All, application, "1.0.1") + val svc = versionsDao.findByApplicationAndVersion(Authorization.All, application, "1.0.1") .flatMap(versionsModel.toModel) - val Some(svc) = versionOpt.map(_.service) + .get.service svc.namespace must be(service.namespace) } diff --git a/api/test/lib/OriginalGeneratorHelpersSpec.scala b/api/test/lib/OriginalGeneratorHelpersSpec.scala index 90e1a53f6..b7290e8c7 100644 --- a/api/test/lib/OriginalGeneratorHelpersSpec.scala +++ b/api/test/lib/OriginalGeneratorHelpersSpec.scala @@ -24,7 +24,7 @@ class OriginalGeneratorHelpersSpec extends PlaySpec with GuiceOneAppPerSuite wit } "serviceJson" in { - OriginalUtil.guessType(readFile("../core/src/test/resources/apibuilder-service.json")) must be(Some(OriginalType.ServiceJson)) + OriginalUtil.guessType(readFile("../core/test/resources/apibuilder-service.json")) must be(Some(OriginalType.ServiceJson)) } "swaggerJson" in { diff --git a/app/app/controllers/AccountController.scala b/app/app/controllers/AccountController.scala index 1c1289337..cc2dfc899 100644 --- a/app/app/controllers/AccountController.scala +++ b/app/app/controllers/AccountController.scala @@ -1,5 +1,7 @@ package controllers +import play.api.mvc.{Action, AnyContent} + import javax.inject.Inject import scala.concurrent.ExecutionContext @@ -9,11 +11,11 @@ class AccountController @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def redirect = Action { implicit request => + def redirect: Action[AnyContent] = Action { implicit request => Redirect(routes.AccountController.index()) } - def index() = Identified { implicit request => + def index(): Action[AnyContent] = Identified { implicit request => Redirect(routes.AccountProfileController.index()) } diff --git a/app/app/controllers/AccountProfileController.scala b/app/app/controllers/AccountProfileController.scala index edfd3d68c..fc507d5fb 100644 --- a/app/app/controllers/AccountProfileController.scala +++ b/app/app/controllers/AccountProfileController.scala @@ -3,8 +3,9 @@ package controllers import io.apibuilder.api.v0.models.UserUpdateForm import javax.inject.Inject -import play.api.data._ -import play.api.data.Forms._ +import play.api.data.* +import play.api.data.Forms.* +import play.api.mvc.{Action, AnyContent} import scala.concurrent.{ExecutionContext, Future} @@ -14,16 +15,16 @@ class AccountProfileController @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def redirect = Action { implicit request => + def redirect: Action[AnyContent] = Action { implicit request => Redirect(routes.AccountProfileController.index()) } - def index() = Identified { implicit request => + def index(): Action[AnyContent] = Identified { implicit request => val tpl = request.mainTemplate(Some("Profile")) Ok(views.html.account.profile.index(tpl, request.user)) } - def edit() = Identified { implicit request => + def edit(): Action[AnyContent] = Identified { implicit request => val form = AccountProfileController.profileForm.fill( AccountProfileController.ProfileData( email = request.user.email, @@ -36,7 +37,7 @@ class AccountProfileController @Inject() ( Ok(views.html.account.profile.edit(tpl, request.user, form)) } - def postEdit = Identified.async { implicit request => + def postEdit: Action[AnyContent] = Identified.async { implicit request => val tpl = request.mainTemplate(Some("Edit Profile")) val form = AccountProfileController.profileForm.bindFromRequest() @@ -75,6 +76,10 @@ object AccountProfileController { name: Option[String] ) + object ProfileData { + def unapply(d: ProfileData): Option[(String, String, Option[String])] = Some((d.email, d.nickname, d.name)) + } + private[controllers] val profileForm = Form( mapping( "email" -> nonEmptyText, diff --git a/app/app/controllers/ApplicationController.scala b/app/app/controllers/ApplicationController.scala index ba7911a81..989adfdd1 100644 --- a/app/app/controllers/ApplicationController.scala +++ b/app/app/controllers/ApplicationController.scala @@ -1,6 +1,7 @@ package controllers import lib.{ApiClientProvider, PaginatedCollection, Pagination} +import play.api.mvc.{Action, AnyContent} import javax.inject.Inject import scala.concurrent.ExecutionContext @@ -12,15 +13,15 @@ class ApplicationController @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def redirect() = Action { request => + def redirect(): Action[AnyContent] = Action { request => Redirect(request.path + "/") } - def redirectOrg(org: String) = Action { request => + def redirectOrg(org: String): Action[AnyContent] = Action { request => Redirect(request.path + "/") } - def index(orgsPage: Int = 0, membershipRequestsPage: Int = 0, publicOrgsPage: Int = 0) = Anonymous.async { implicit request => + def index(orgsPage: Int = 0, membershipRequestsPage: Int = 0, publicOrgsPage: Int = 0): Action[AnyContent] = Anonymous.async { implicit request => request.user match { case None => { for { diff --git a/app/app/controllers/ApplicationSettings.scala b/app/app/controllers/ApplicationSettings.scala index 8f41e86b1..e28c3dfe0 100644 --- a/app/app/controllers/ApplicationSettings.scala +++ b/app/app/controllers/ApplicationSettings.scala @@ -4,10 +4,10 @@ import io.apibuilder.api.v0.models.{ApplicationForm, MoveForm, Visibility} import javax.inject.Inject import lib.ApiClientProvider -import models._ -import play.api.data.Forms._ -import play.api.data._ -import play.api.mvc.Result +import models.* +import play.api.data.Forms.* +import play.api.data.* +import play.api.mvc.{Action, AnyContent, Result} import scala.concurrent.{ExecutionContext, Future} @@ -63,7 +63,7 @@ class ApplicationSettings @Inject() ( } } - def show(orgKey: String, applicationKey: String, versionName: String) = IdentifiedOrg.async { implicit request => + def show(orgKey: String, applicationKey: String, versionName: String): Action[AnyContent] = IdentifiedOrg.async { implicit request => for { tpl <- mainTemplate(request.api, request.mainTemplate(None), applicationKey, versionName) } yield { @@ -73,7 +73,7 @@ class ApplicationSettings @Inject() ( } } - def edit(orgKey: String, applicationKey: String, versionName: String) = IdentifiedOrg.async { implicit request => + def edit(orgKey: String, applicationKey: String, versionName: String): Action[AnyContent] = IdentifiedOrg.async { implicit request => for { tpl <- mainTemplate(request.api, request.mainTemplate(None), applicationKey, versionName) } yield { @@ -84,7 +84,7 @@ class ApplicationSettings @Inject() ( } } - def postEdit(orgKey: String, applicationKey: String, versionName: String) = IdentifiedOrg.async { implicit request => + def postEdit(orgKey: String, applicationKey: String, versionName: String): Action[AnyContent] = IdentifiedOrg.async { implicit request => mainTemplate(request.api, request.mainTemplate(None), applicationKey, versionName).flatMap { result => result match { case Left(error) => Future { @@ -121,7 +121,7 @@ class ApplicationSettings @Inject() ( } } - def postDelete(orgKey: String, applicationKey: String) = IdentifiedOrg.async { implicit request => + def postDelete(orgKey: String, applicationKey: String): Action[AnyContent] = IdentifiedOrg.async { implicit request => for { result <- request.api.Applications.deleteByApplicationKey(request.org.key, applicationKey) } yield { @@ -129,7 +129,7 @@ class ApplicationSettings @Inject() ( } } - def move(orgKey: String, applicationKey: String) = IdentifiedOrg.async { implicit request => + def move(orgKey: String, applicationKey: String): Action[AnyContent] = IdentifiedOrg.async { implicit request => for { tpl <- mainTemplate(request.api, request.mainTemplate(None), applicationKey) } yield { @@ -139,7 +139,7 @@ class ApplicationSettings @Inject() ( } } - def postMove(orgKey: String, applicationKey: String) = IdentifiedOrg.async { implicit request => + def postMove(orgKey: String, applicationKey: String): Action[AnyContent] = IdentifiedOrg.async { implicit request => mainTemplate(request.api, request.mainTemplate(None), applicationKey).flatMap { result => result match { case Left(error) => Future { @@ -177,6 +177,9 @@ class ApplicationSettings @Inject() ( object ApplicationSettings { case class Settings(visibility: String) + object Settings { + def unapply(s: Settings): Option[String] = Some(s.visibility) + } private[controllers] val settingsForm = Form( mapping( "visibility" -> text @@ -184,6 +187,9 @@ object ApplicationSettings { ) case class MoveOrgData(orgKey: String) + object MoveOrgData { + def unapply(d: MoveOrgData): Option[String] = Some(d.orgKey) + } private[controllers] val moveOrgForm = Form( mapping( "org_key" -> text diff --git a/app/app/controllers/AttributesController.scala b/app/app/controllers/AttributesController.scala index 2cd2f50b6..2f3500aef 100644 --- a/app/app/controllers/AttributesController.scala +++ b/app/app/controllers/AttributesController.scala @@ -5,8 +5,9 @@ import lib.{ApiClientProvider, PaginatedCollection, Pagination} import scala.concurrent.{ExecutionContext, Future} import javax.inject.Inject -import play.api.data.Forms._ -import play.api.data._ +import play.api.data.Forms.* +import play.api.data.* +import play.api.mvc.{Action, AnyContent} class AttributesController @Inject() ( val apiBuilderControllerComponents: ApiBuilderControllerComponents, @@ -15,7 +16,7 @@ class AttributesController @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def index(page: Int = 0) = Anonymous.async { implicit request => + def index(page: Int = 0): Action[AnyContent] = Anonymous.async { implicit request => for { attributes <- request.api.attributes.get( limit = Pagination.DefaultLimit+1, @@ -29,7 +30,7 @@ class AttributesController @Inject() ( } } - def show(name: String, page: Int) = Anonymous.async { implicit request => + def show(name: String, page: Int): Action[AnyContent] = Anonymous.async { implicit request => for { attribute <- apiClientProvider.callWith404(request.api.attributes.getByName(name)) generators <- request.api.generatorWithServices.get( @@ -51,7 +52,7 @@ class AttributesController @Inject() ( } } - def create() = Identified { implicit request => + def create(): Action[AnyContent] = Identified { implicit request => val filledForm = AttributesController.attributesFormData.fill( AttributesController.AttributeFormData( name = "", @@ -62,7 +63,7 @@ class AttributesController @Inject() ( Ok(views.html.attributes.create(request.mainTemplate(), filledForm)) } - def createPost = Identified.async { implicit request => + def createPost: Action[AnyContent] = Identified.async { implicit request => val tpl = request.mainTemplate(Some("Add Attribute")) val form = AttributesController.attributesFormData.bindFromRequest() @@ -90,7 +91,7 @@ class AttributesController @Inject() ( ) } - def deletePost(name: String) = Identified.async { implicit request => + def deletePost(name: String): Action[AnyContent] = Identified.async { implicit request => apiClientProvider.callWith404(request.api.attributes.deleteByName(name)).map { case None => Redirect(routes.AttributesController.index()).flashing("warning" -> s"Attribute not found") case Some(_) => Redirect(routes.AttributesController.index()).flashing("success" -> s"Attribute deleted") @@ -104,6 +105,11 @@ object AttributesController { name: String, description: String ) + object AttributeFormData { + def unapply(d: AttributeFormData): Option[(String, String)] = Some( + (d.name, d.description) + ) + } private[controllers] val attributesFormData = Form( mapping( diff --git a/app/app/controllers/Domains.scala b/app/app/controllers/Domains.scala index c4f72d1d0..8f8aa58f2 100644 --- a/app/app/controllers/Domains.scala +++ b/app/app/controllers/Domains.scala @@ -2,9 +2,10 @@ package controllers import io.apibuilder.api.v0.models.Domain import lib.ApiClientProvider -import models._ -import play.api.data._ -import play.api.data.Forms._ +import models.* +import play.api.data.* +import play.api.data.Forms.* +import play.api.mvc.{Action, AnyContent} import scala.concurrent.{ExecutionContext, Future} import javax.inject.Inject @@ -16,21 +17,21 @@ class Domains @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def index(orgKey: String) = IdentifiedOrg { implicit request => + def index(orgKey: String): Action[AnyContent] = IdentifiedOrg { implicit request => request.withMember { val tpl = request.mainTemplate(title = Some("Domains")) Ok(views.html.domains.index(tpl.copy(settings = Some(SettingsMenu(section = Some(SettingSection.Domains)))))) } } - def create(orgKey: String) = IdentifiedOrg { implicit request => + def create(orgKey: String): Action[AnyContent] = IdentifiedOrg { implicit request => request.withAdmin { val tpl = request.mainTemplate(title = Some("Add Domain")) Ok(views.html.domains.form(tpl, Domains.domainForm)) } } - def postCreate(orgKey: String) = IdentifiedOrg.async { implicit request => + def postCreate(orgKey: String): Action[AnyContent] = IdentifiedOrg.async { implicit request => request.withAdmin { val tpl = request.mainTemplate(title = Some("Add Domain")) val boundForm = Domains.domainForm.bindFromRequest() @@ -57,7 +58,7 @@ class Domains @Inject() ( } } - def postRemove(orgKey: String, domain: String) = IdentifiedOrg.async { implicit request => + def postRemove(orgKey: String, domain: String): Action[AnyContent] = IdentifiedOrg.async { implicit request => request.withAdmin { for { _ <- request.api.Domains.deleteByName(orgKey, domain) @@ -72,6 +73,10 @@ class Domains @Inject() ( object Domains { case class DomainData(name: String) + object DomainData { + def unapply(d: DomainData): Option[String] = Some(d.name) + } + private[controllers] val domainForm = Form( mapping( "name" -> nonEmptyText diff --git a/app/app/controllers/EmailVerifications.scala b/app/app/controllers/EmailVerifications.scala index 266e660b0..7ed59b758 100644 --- a/app/app/controllers/EmailVerifications.scala +++ b/app/app/controllers/EmailVerifications.scala @@ -2,6 +2,7 @@ package controllers import javax.inject.Inject import io.apibuilder.api.v0.models.EmailVerificationConfirmationForm +import play.api.mvc.{Action, AnyContent} import scala.concurrent.ExecutionContext @@ -11,7 +12,7 @@ class EmailVerifications @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def get(token: String) = Anonymous.async { implicit request => + def get(token: String): Action[AnyContent] = Anonymous.async { implicit request => request.api.emailVerificationConfirmationForms.post( EmailVerificationConfirmationForm(token = token) ).map { _ => diff --git a/app/app/controllers/GeneratorServices.scala b/app/app/controllers/GeneratorServices.scala index 6ae28e161..a5673a79f 100644 --- a/app/app/controllers/GeneratorServices.scala +++ b/app/app/controllers/GeneratorServices.scala @@ -1,6 +1,7 @@ package controllers import lib.{ApiClientProvider, PaginatedCollection, Pagination} +import play.api.mvc.{Action, AnyContent} import java.util.UUID import javax.inject.Inject @@ -13,7 +14,7 @@ class GeneratorServices @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def show(guid: UUID, page: Int = 0) = Anonymous.async { implicit request => + def show(guid: UUID, page: Int = 0): Action[AnyContent] = Anonymous.async { implicit request => for { serviceOption <- apiClientProvider.callWith404(request.api.generatorServices.getByGuid(guid)) generators <- request.api.generatorWithServices.get( @@ -37,7 +38,7 @@ class GeneratorServices @Inject() ( } } - def deletePost(guid: UUID) = Anonymous.async { implicit request => + def deletePost(guid: UUID): Action[AnyContent] = Anonymous.async { implicit request => for { _ <- request.api.generatorServices.deleteByGuid(guid) } yield { diff --git a/app/app/controllers/Generators.scala b/app/app/controllers/Generators.scala index 86359ba5e..666a661bb 100644 --- a/app/app/controllers/Generators.scala +++ b/app/app/controllers/Generators.scala @@ -2,8 +2,9 @@ package controllers import io.apibuilder.api.v0.models.GeneratorServiceForm import lib.{ApiClientProvider, PaginatedCollection, Pagination} -import play.api.data.Forms._ -import play.api.data._ +import play.api.data.Forms.* +import play.api.data.* +import play.api.mvc.{Action, AnyContent} import scala.concurrent.{ExecutionContext, Future} import javax.inject.Inject @@ -15,11 +16,11 @@ class Generators @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def redirect = Action { implicit request => + def redirect: Action[AnyContent] = Action { implicit request => Redirect(routes.Generators.index()) } - def index(page: Int = 0) = Anonymous.async { implicit request => + def index(page: Int = 0): Action[AnyContent] = Anonymous.async { implicit request => for { generators <- request.api.generatorWithServices.get( limit = Pagination.DefaultLimit+1, @@ -33,7 +34,7 @@ class Generators @Inject() ( } } - def show(key: String) = Anonymous.async { implicit request => + def show(key: String): Action[AnyContent] = Anonymous.async { implicit request => for { generator <- apiClientProvider.callWith404(request.api.generatorWithServices.getByKey(key)) } yield { @@ -49,7 +50,7 @@ class Generators @Inject() ( } } - def create() = Identified { implicit request => + def create(): Action[AnyContent] = Identified { implicit request => val filledForm = Generators.generatorServiceCreateFormData.fill( Generators.GeneratorServiceCreateFormData( uri = "" @@ -59,7 +60,7 @@ class Generators @Inject() ( Ok(views.html.generators.create(request.mainTemplate(), filledForm)) } - def createPost = Identified.async { implicit request => + def createPost: Action[AnyContent] = Identified.async { implicit request => val form = Generators.generatorServiceCreateFormData.bindFromRequest() form.fold ( @@ -91,6 +92,9 @@ object Generators { case class GeneratorServiceCreateFormData( uri: String ) + object GeneratorServiceCreateFormData { + def unapply(d: GeneratorServiceCreateFormData): Option[String] = Some(d.uri) + } private[controllers] val generatorServiceCreateFormData = Form( mapping( diff --git a/app/app/controllers/GithubController.scala b/app/app/controllers/GithubController.scala index c245f38b8..119ca0bec 100644 --- a/app/app/controllers/GithubController.scala +++ b/app/app/controllers/GithubController.scala @@ -17,18 +17,18 @@ class GithubController @javax.inject.Inject() ( import scala.concurrent.ExecutionContext.Implicits.global - def redirect(returnUrl: Option[String]) = Action { + def redirect(returnUrl: Option[String]): Action[AnyContent] = Action { Redirect(routes.GithubController.index(returnUrl)) } - def index(returnUrl: Option[String]) = Action { + def index(returnUrl: Option[String]): Action[AnyContent] = Action { Redirect(github.oauthUrl(returnUrl = returnUrl)) } def callback( code: String, returnUrl: String - ) = Anonymous.async { request => + ): Action[AnyContent] = Anonymous.async { request => getAccessToken(code).flatMap { case Left(ex) => Future.successful { logger.error(s"Unable to process git hub login: ${ex.getMessage}", ex) @@ -52,6 +52,8 @@ class GithubController @javax.inject.Inject() ( } private def getAccessToken(code: String): Future[Either[Throwable, String]] = { + import play.api.libs.ws.JsonBodyWritables.writeableOf_JsValue + val form = Json.obj( "client_id" -> github.clientId, "client_secret" -> github.clientSecret, @@ -60,9 +62,7 @@ class GithubController @javax.inject.Inject() ( ws.url("https://github.com/login/oauth/access_token").post(form).map { result => val parsed = FormUrlEncodedParser.parse(result.body) - val accessToken = parsed.get("access_token").getOrElse { - sys.error(s"GitHub Oauth response did not contain an access_token: ${result.body}") - }.headOption.getOrElse { + val accessToken = parsed.getOrElse("access_token", sys.error(s"GitHub Oauth response did not contain an access_token: ${result.body}")).headOption.getOrElse { sys.error(s"GitHub Oauth response returned an empty list for access_token: ${result.body}") } Right(accessToken) diff --git a/app/app/controllers/Healthchecks.scala b/app/app/controllers/Healthchecks.scala index 5425072fb..856747a77 100644 --- a/app/app/controllers/Healthchecks.scala +++ b/app/app/controllers/Healthchecks.scala @@ -1,6 +1,7 @@ package controllers import models.MainTemplate +import play.api.mvc.{Action, AnyContent} import javax.inject.Inject import scala.concurrent.ExecutionContext @@ -11,7 +12,7 @@ class Healthchecks @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def index() = Anonymous.async { implicit request => + def index(): Action[AnyContent] = Anonymous.async { implicit request => for { orgs <- request.api.organizations.get(key = Some("apicollective"), limit = 1) } yield { diff --git a/app/app/controllers/HistoryController.scala b/app/app/controllers/HistoryController.scala index 7fbb8c123..9e6bde7f1 100644 --- a/app/app/controllers/HistoryController.scala +++ b/app/app/controllers/HistoryController.scala @@ -1,6 +1,7 @@ package controllers import lib.{PaginatedCollection, Pagination} +import play.api.mvc.{Action, AnyContent} import javax.inject.Inject import scala.concurrent.ExecutionContext @@ -18,7 +19,7 @@ class HistoryController @Inject() ( to: Option[String], `type`: Option[String], page: Int = 0 - ) = Anonymous.async { implicit request => + ): Action[AnyContent] = Anonymous.async { implicit request => for { changes <- request.api.changes.get( orgKey = orgKey, diff --git a/app/app/controllers/LoginController.scala b/app/app/controllers/LoginController.scala index e2b8a3612..71c393ae5 100644 --- a/app/app/controllers/LoginController.scala +++ b/app/app/controllers/LoginController.scala @@ -3,13 +3,13 @@ package controllers import io.apibuilder.api.v0.models.{PasswordReset, PasswordResetRequest} import lib.{ApiClientProvider, Github, Util} import models.MainTemplate -import play.api.data._ -import play.api.data.Forms._ +import play.api.data.* +import play.api.data.Forms.* import scala.concurrent.Future import javax.inject.Inject - import play.api.Logger +import play.api.mvc.{Action, AnyContent} class LoginController @Inject() ( val apiBuilderControllerComponents: ApiBuilderControllerComponents, @@ -24,11 +24,11 @@ class LoginController @Inject() ( private val DevSessionId = "dev" - def redirect = Action { + def redirect: Action[AnyContent] = Action { Redirect(routes.LoginController.index()) } - def developmentLogin = Anonymous.async { request => + def developmentLogin: Action[AnyContent] = Anonymous.async { request => request.api.authentications.getSessionById(DevSessionId).map { result => Redirect("/"). withSession { "session_id" -> result.session.id }. @@ -42,19 +42,19 @@ class LoginController @Inject() ( } } - def index(returnUrl: Option[String]) = Action { implicit request => + def index(returnUrl: Option[String]): Action[AnyContent] = Action { implicit request => val tpl = MainTemplate(requestPath = request.path) Ok(views.html.login.index(tpl, github, LoginController.Tab.Login, returnUrl)) } - def legacy(returnUrl: Option[String]) = Action { implicit request => + def legacy(returnUrl: Option[String]): Action[AnyContent] = Action { implicit request => val tpl = MainTemplate(requestPath = request.path) val lForm = LoginController.loginForm.fill(LoginController.LoginData(email = "", password = "", returnUrl = returnUrl)) val rForm = LoginController.registerForm.fill(LoginController.RegisterData(name = None, email = "", password = "", passwordVerify = "", returnUrl = returnUrl)) Ok(views.html.login.legacy(tpl, LoginController.Tab.Login, lForm, rForm)) } - def legacyPost = Anonymous.async { implicit request => + def legacyPost: Action[AnyContent] = Anonymous.async { implicit request => val tpl = MainTemplate(requestPath = request.path) val form = LoginController.loginForm.bindFromRequest() form.fold ( @@ -93,12 +93,12 @@ class LoginController @Inject() ( ) } - def forgotPassword() = Action { implicit request => + def forgotPassword(): Action[AnyContent] = Action { implicit request => val tpl = MainTemplate(requestPath = request.path) Ok(views.html.login.forgotPassword(tpl, LoginController.forgotPasswordForm)) } - def postForgotPassword = Anonymous.async { implicit request => + def postForgotPassword: Action[AnyContent] = Anonymous.async { implicit request => val tpl = MainTemplate(requestPath = request.path) val form = LoginController.forgotPasswordForm.bindFromRequest() form.fold ( @@ -119,12 +119,12 @@ class LoginController @Inject() ( ) } - def resetPassword(token: String) = Action { implicit request => + def resetPassword(token: String): Action[AnyContent] = Action { implicit request => val tpl = MainTemplate(requestPath = request.path) Ok(views.html.login.resetPassword(tpl, token, LoginController.resetPasswordForm)) } - def postResetPassword(token: String) = Anonymous.async { implicit request => + def postResetPassword(token: String): Action[AnyContent] = Anonymous.async { implicit request => val tpl = MainTemplate(requestPath = request.path) val form = LoginController.resetPasswordForm.bindFromRequest() form.fold ( @@ -155,7 +155,13 @@ class LoginController @Inject() ( object LoginController { case class LoginData(email: String, password: String, returnUrl: Option[String]) - val loginForm = Form( + object LoginData { + def unapply(d: LoginData): Option[(String, String, Option[String])] = { + Some(d.email, d.password, d.returnUrl) + } + } + + val loginForm: Form[LoginData] = Form( mapping( "email" -> nonEmptyText, "password" -> nonEmptyText, @@ -164,7 +170,12 @@ object LoginController { ) case class RegisterData(name: Option[String], email: String, password: String, passwordVerify: String, returnUrl: Option[String]) - val registerForm = Form( + object RegisterData { + def unapply(d: RegisterData): Option[(Option[String], String, String, String, Option[String])] = { + Some((d.name, d.email, d.password, d.passwordVerify, d.returnUrl)) + } + } + val registerForm: Form[RegisterData] = Form( mapping( "name" -> optional(text), "email" -> nonEmptyText, @@ -177,14 +188,21 @@ object LoginController { ) case class ForgotPasswordData(email: String) - val forgotPasswordForm = Form( + object ForgotPasswordData { + def unapply(d: ForgotPasswordData): Option[String] = Some(d.email) + } + private val forgotPasswordForm: Form[ForgotPasswordData] = Form( mapping( "email" -> nonEmptyText )(ForgotPasswordData.apply)(ForgotPasswordData.unapply) ) case class ResetPasswordData(password: String, passwordVerify: String) - val resetPasswordForm = Form( + object ResetPasswordData { + def unapply(d: ResetPasswordData): Option[(String, String)] = Some((d.password, d.passwordVerify)) + } + + private val resetPasswordForm: Form[ResetPasswordData] = Form( mapping( "password" -> nonEmptyText(minLength=5), "password_verify" -> nonEmptyText diff --git a/app/app/controllers/LogoutController.scala b/app/app/controllers/LogoutController.scala index df3069bff..9affce37a 100644 --- a/app/app/controllers/LogoutController.scala +++ b/app/app/controllers/LogoutController.scala @@ -1,6 +1,8 @@ package controllers import models.MainTemplate +import play.api.mvc.{Action, AnyContent} + import javax.inject.Inject class LogoutController @Inject() ( @@ -8,11 +10,11 @@ class LogoutController @Inject() ( ) extends ApiBuilderController { - def logged_out = Action { implicit request => + def logged_out: Action[AnyContent] = Action { implicit request => Ok(views.html.logged_out(MainTemplate(requestPath = request.path))) } - def logout = Action { + def logout: Action[AnyContent] = Action { Redirect("/logged_out").withNewSession } diff --git a/app/app/controllers/Members.scala b/app/app/controllers/Members.scala index 0b39112c7..5cdd9bfa6 100644 --- a/app/app/controllers/Members.scala +++ b/app/app/controllers/Members.scala @@ -1,15 +1,16 @@ package controllers -import lib._ +import lib.* import io.apibuilder.api.v0.models.{Organization, User} import io.apibuilder.common.v0.models.MembershipRole -import models._ -import play.api.data._ -import play.api.data.Forms._ +import models.* +import play.api.data.* +import play.api.data.Forms.* import scala.concurrent.{Await, ExecutionContext} -import scala.concurrent.duration._ +import scala.concurrent.duration.* import org.joda.time.DateTime +import play.api.mvc.{Action, AnyContent} import java.util.UUID import javax.inject.Inject @@ -21,7 +22,7 @@ class Members @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def show(orgKey: String, page: Int = 0) = IdentifiedOrg.async { implicit request => + def show(orgKey: String, page: Int = 0): Action[AnyContent] = IdentifiedOrg.async { implicit request => request.withMember { for { orgs <- request.api.Organizations.get(key = Some(orgKey)) @@ -47,7 +48,7 @@ class Members @Inject() ( } } - def add(orgKey: String) = IdentifiedOrg { implicit request => + def add(orgKey: String): Action[AnyContent] = IdentifiedOrg { implicit request => request.withMember { val filledForm = Members.addMemberForm.fill(Members.AddMemberData(role = MembershipRole.Member.toString, email = "", nickname = "")) @@ -56,7 +57,7 @@ class Members @Inject() ( } } - def addPost(orgKey: String) = IdentifiedOrg { implicit request => + def addPost(orgKey: String): Action[AnyContent] = IdentifiedOrg { implicit request => request.withMember { val tpl = request.mainTemplate(Some("Add Member")).copy(settings = Some(SettingsMenu(section = Some(SettingSection.Members)))) @@ -93,7 +94,7 @@ class Members @Inject() ( } } - def postRemove(orgKey: String, guid: UUID) = IdentifiedOrg.async { implicit request => + def postRemove(orgKey: String, guid: UUID): Action[AnyContent] = IdentifiedOrg.async { implicit request => request.withAdmin { for { _ <- request.api.Memberships.deleteByGuid(guid) @@ -103,7 +104,7 @@ class Members @Inject() ( } } - def postRevokeAdmin(orgKey: String, guid: UUID) = IdentifiedOrg.async { implicit request => + def postRevokeAdmin(orgKey: String, guid: UUID): Action[AnyContent] = IdentifiedOrg.async { implicit request => request.withAdmin { for { membership <- apiClientProvider.callWith404(request.api.Memberships.getByGuid(guid)) @@ -130,7 +131,7 @@ class Members @Inject() ( } } - def postMakeAdmin(orgKey: String, guid: UUID) = IdentifiedOrg.async { implicit request => + def postMakeAdmin(orgKey: String, guid: UUID): Action[AnyContent] = IdentifiedOrg.async { implicit request => request.withAdmin { for { membership <- apiClientProvider.callWith404(request.api.Memberships.getByGuid(guid)) @@ -156,7 +157,7 @@ class Members @Inject() ( } } - def downloadCsv(orgKey: String) = IdentifiedOrg.async { implicit request => + def downloadCsv(orgKey: String): Action[AnyContent] = IdentifiedOrg.async { implicit request => request.withAdmin { for { path <- MemberDownload(request.api, orgKey).csv() @@ -192,6 +193,9 @@ class Members @Inject() ( object Members { case class AddMemberData(role: String, email: String, nickname: String) + object AddMemberData { + def unapply(d: AddMemberData): Option[(String, String, String)] = Some((d.role, d.email, d.nickname)) + } private[controllers] val addMemberForm = Form( mapping( "role" -> default(nonEmptyText, MembershipRole.Member.toString), diff --git a/app/app/controllers/MembershipRequestReviews.scala b/app/app/controllers/MembershipRequestReviews.scala index 5a703f7d6..60ceab168 100644 --- a/app/app/controllers/MembershipRequestReviews.scala +++ b/app/app/controllers/MembershipRequestReviews.scala @@ -1,5 +1,7 @@ package controllers +import play.api.mvc.{Action, AnyContent} + import java.util.UUID import javax.inject.Inject import scala.concurrent.ExecutionContext @@ -10,7 +12,7 @@ class MembershipRequestReviews @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def accept(orgKey: String, membershipRequestGuid: UUID) = IdentifiedOrg.async { implicit request => + def accept(orgKey: String, membershipRequestGuid: UUID): Action[AnyContent] = IdentifiedOrg.async { implicit request => request.withAdmin { for { _ <- request.api.MembershipRequests.postAcceptByGuid(membershipRequestGuid) @@ -20,7 +22,7 @@ class MembershipRequestReviews @Inject() ( } } - def decline(orgKey: String, membershipRequestGuid: UUID) = IdentifiedOrg.async { implicit request => + def decline(orgKey: String, membershipRequestGuid: UUID): Action[AnyContent] = IdentifiedOrg.async { implicit request => request.withAdmin { for { _ <- request.api.MembershipRequests.postDeclineByGuid(membershipRequestGuid) diff --git a/app/app/controllers/OrganizationAttributesController.scala b/app/app/controllers/OrganizationAttributesController.scala index c00aea7bd..519102666 100644 --- a/app/app/controllers/OrganizationAttributesController.scala +++ b/app/app/controllers/OrganizationAttributesController.scala @@ -2,8 +2,9 @@ package controllers import io.apibuilder.api.v0.models.AttributeValueForm import models.{SettingSection, SettingsMenu} -import play.api.data.Forms._ -import play.api.data._ +import play.api.data.Forms.* +import play.api.data.* +import play.api.mvc.{Action, AnyContent} import javax.inject.Inject import scala.concurrent.{ExecutionContext, Future} @@ -14,11 +15,11 @@ class OrganizationAttributesController @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def redirect = Action { implicit request => + def redirect: Action[AnyContent] = Action { implicit request => Redirect(routes.AttributesController.index()) } - def index(orgKey: String) = IdentifiedOrg.async { implicit request => + def index(orgKey: String): Action[AnyContent] = IdentifiedOrg.async { implicit request => // TODO: Paginate once we exceed limit for { attributes <- request.api.attributes.get( @@ -44,7 +45,7 @@ class OrganizationAttributesController @Inject() ( } } - def edit(orgKey: String, name: String) = IdentifiedOrg.async { implicit request => + def edit(orgKey: String, name: String): Action[AnyContent] = IdentifiedOrg.async { implicit request => for { attr <- request.api.attributes.getByName(name) values <- request.api.organizations.getAttributesByKey( @@ -63,7 +64,7 @@ class OrganizationAttributesController @Inject() ( } } - def editPost(orgKey: String, name: String) = IdentifiedOrg.async { implicit request => + def editPost(orgKey: String, name: String): Action[AnyContent] = IdentifiedOrg.async { implicit request => request.api.attributes.getByName(name).flatMap { attr => val tpl = request.mainTemplate(Some("Edit Attribute")) @@ -113,6 +114,10 @@ object OrganizationAttributesController { value: Option[String] ) + object FormData { + def unapply(d: FormData): Option[Option[String]] = Some(d.value) + } + private[controllers] val formData = Form( mapping( "value" -> optional(text) diff --git a/app/app/controllers/Organizations.scala b/app/app/controllers/Organizations.scala index b840f0831..a94985f43 100644 --- a/app/app/controllers/Organizations.scala +++ b/app/app/controllers/Organizations.scala @@ -252,6 +252,11 @@ object Organizations { key: Option[String], visibility: String ) + object OrgData { + def unapply(d: OrgData): Option[(String, String, Option[String], String)] = { + Some((d.name, d.namespace, d.key, d.visibility)) + } + } private[controllers] val orgForm = Form( mapping( diff --git a/app/app/controllers/SearchController.scala b/app/app/controllers/SearchController.scala index c7746382f..6674d526f 100644 --- a/app/app/controllers/SearchController.scala +++ b/app/app/controllers/SearchController.scala @@ -1,6 +1,7 @@ package controllers import lib.{PaginatedCollection, Pagination, Util} +import play.api.mvc.{Action, AnyContent} import javax.inject.Inject import scala.concurrent.ExecutionContext @@ -12,7 +13,7 @@ class SearchController @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def index(q: Option[String], org: Option[String], page: Int = 0) = Anonymous.async { implicit request => + def index(q: Option[String], org: Option[String], page: Int = 0): Action[AnyContent] = Anonymous.async { implicit request => val finalQuery = Seq( org.map { key => s"org:$key" }, q diff --git a/app/app/controllers/Subscriptions.scala b/app/app/controllers/Subscriptions.scala index 79f84e525..b0a6b290f 100644 --- a/app/app/controllers/Subscriptions.scala +++ b/app/app/controllers/Subscriptions.scala @@ -2,6 +2,7 @@ package controllers import lib.Labels import io.apibuilder.api.v0.models.{Publication, SubscriptionForm} +import play.api.mvc.{Action, AnyContent} import javax.inject.Inject @@ -26,7 +27,7 @@ class Subscriptions @Inject() ( import scala.concurrent.ExecutionContext.Implicits.global - def offerPublication(isAdmin: Boolean, publication: Publication): Boolean = { + private def offerPublication(isAdmin: Boolean, publication: Publication): Boolean = { publication match { case Publication.MembershipRequestsCreate => isAdmin case Publication.MembershipsCreate => isAdmin @@ -39,7 +40,7 @@ class Subscriptions @Inject() ( def index( org: String - ) = IdentifiedOrg.async { implicit request => + ): Action[AnyContent] = IdentifiedOrg.async { implicit request => for { subscriptions <- request.api.subscriptions.get( organizationKey = Some(request.org.key), @@ -60,7 +61,7 @@ class Subscriptions @Inject() ( def postToggle( org: String, publication: Publication - ) = IdentifiedOrg.async { implicit request => + ): Action[AnyContent] = IdentifiedOrg.async { implicit request => request.api.subscriptions.get( organizationKey = Some(request.org.key), userGuid = Some(request.user.guid), diff --git a/app/app/controllers/TokensController.scala b/app/app/controllers/TokensController.scala index 3273a06f8..aaa2ceb66 100644 --- a/app/app/controllers/TokensController.scala +++ b/app/app/controllers/TokensController.scala @@ -4,8 +4,9 @@ import java.util.UUID import javax.inject.Inject import io.apibuilder.api.v0.models.TokenForm import lib.{ApiClientProvider, PaginatedCollection, Pagination} -import play.api.data._ -import play.api.data.Forms._ +import play.api.data.* +import play.api.data.Forms.* +import play.api.mvc.{Action, AnyContent} import scala.concurrent.{ExecutionContext, Future} @@ -16,11 +17,11 @@ class TokensController @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def redirect = Action { implicit request => + def redirect: Action[AnyContent] = Action { implicit request => Redirect(routes.TokensController.index()) } - def index(page: Int = 0) = Identified.async { implicit request => + def index(page: Int = 0): Action[AnyContent] = Identified.async { implicit request => for { tokens <- request.api.tokens.getUsersByUserGuid( request.user.guid, @@ -32,7 +33,7 @@ class TokensController @Inject() ( } } - def show(guid: UUID) = Identified.async { implicit request => + def show(guid: UUID): Action[AnyContent] = Identified.async { implicit request => for { tokens <- request.api.tokens.getUsersByUserGuid( request.user.guid, @@ -50,7 +51,7 @@ class TokensController @Inject() ( } } - def cleartext(guid: UUID) = Identified.async { implicit request => + def cleartext(guid: UUID): Action[AnyContent] = Identified.async { implicit request => for { cleartextOption <- apiClientProvider.callWith404(request.api.tokens.getCleartextByGuid(guid)) } yield { @@ -65,11 +66,11 @@ class TokensController @Inject() ( } } - def create() = Identified { implicit request => + def create(): Action[AnyContent] = Identified { implicit request => Ok(views.html.tokens.create(request.mainTemplate(Some("Create token")), TokensController.tokenForm)) } - def postCreate = Identified.async { implicit request => + def postCreate: Action[AnyContent] = Identified.async { implicit request => val tpl = request.mainTemplate(Some("Create token")) val form = TokensController.tokenForm.bindFromRequest() @@ -97,7 +98,7 @@ class TokensController @Inject() ( ) } - def postDelete(guid: UUID) = Identified.async { implicit request => + def postDelete(guid: UUID): Action[AnyContent] = Identified.async { implicit request => for { _ <- request.api.tokens.deleteByGuid(guid) } yield { @@ -111,6 +112,9 @@ object TokensController { case class TokenData( description: Option[String] ) + object TokenData { + def unapply(d: TokenData): Option[Option[String]] = Some(d.description) + } private[controllers] val tokenForm = Form( mapping( diff --git a/app/app/controllers/Versions.scala b/app/app/controllers/Versions.scala index d6028014d..935d95cc5 100644 --- a/app/app/controllers/Versions.scala +++ b/app/app/controllers/Versions.scala @@ -2,14 +2,16 @@ package controllers import java.io.File import javax.inject.Inject -import io.apibuilder.api.v0.models._ -import io.apibuilder.spec.v0.models.json._ +import io.apibuilder.api.v0.models.* +import io.apibuilder.spec.v0.models.json.* import lib.{ApiClientProvider, FileUtils, Labels, VersionTag} -import play.api.data.Forms._ -import play.api.data._ -import play.api.libs.json._ +import play.api.data.Forms.* +import play.api.data.* +import play.api.libs.Files +import play.api.libs.json.* +import play.api.mvc.{Action, AnyContent, MultipartFormData} -import scala.concurrent.duration._ +import scala.concurrent.duration.* import scala.concurrent.{Await, ExecutionContext, Future} class Versions @Inject() ( @@ -22,11 +24,11 @@ class Versions @Inject() ( private implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global - def redirectToLatest(orgKey: String, applicationKey: String) = Action { + def redirectToLatest(orgKey: String, applicationKey: String): Action[AnyContent] = Action { Redirect(routes.Versions.show(orgKey, applicationKey, LatestVersion)) } - def show(orgKey: String, applicationKey: String, versionName: String) = AnonymousOrg.async { implicit request => + def show(orgKey: String, applicationKey: String, versionName: String): Action[AnyContent] = AnonymousOrg.async { implicit request => for { applicationResponse <- request.api.applications.get(orgKey = orgKey, key = Some(applicationKey)) versionsResponse <- request.api.versions.getByApplicationKey(orgKey, applicationKey) @@ -74,7 +76,7 @@ class Versions @Inject() ( } } - def original(orgKey: String, applicationKey: String, versionName: String) = AnonymousOrg.async { implicit request => + def original(orgKey: String, applicationKey: String, versionName: String): Action[AnyContent] = AnonymousOrg.async { implicit request => apiClientProvider.callWith404( request.api.versions.getByApplicationKeyAndVersion(orgKey, applicationKey, versionName) ).map { @@ -112,7 +114,7 @@ class Versions @Inject() ( def example( orgKey: String, applicationKey: String, versionName: String, typeName: String, subTypeName: Option[String], optionalFields: Option[Boolean] - ) = AnonymousOrg.async { implicit request => + ): Action[AnyContent] = AnonymousOrg.async { implicit request => apiClientProvider.callWith404( request.api.versions.getExampleByApplicationKeyAndVersionAndTypeName(orgKey, applicationKey, versionName, typeName, subTypeName = subTypeName, optionalFields = optionalFields) ).map { @@ -131,7 +133,7 @@ class Versions @Inject() ( } } - def serviceJson(orgKey: String, applicationKey: String, versionName: String) = AnonymousOrg.async { implicit request => + def serviceJson(orgKey: String, applicationKey: String, versionName: String): Action[AnyContent] = AnonymousOrg.async { implicit request => apiClientProvider.callWith404( request.api.versions.getByApplicationKeyAndVersion(orgKey, applicationKey, versionName) ).map { @@ -149,7 +151,7 @@ class Versions @Inject() ( } } - def postDelete(orgKey: String, applicationKey: String, versionName: String) = AnonymousOrg.async { implicit request => + def postDelete(orgKey: String, applicationKey: String, versionName: String): Action[AnyContent] = AnonymousOrg.async { implicit request => for { result <- apiClientProvider.callWith404( request.api.versions.deleteByApplicationKeyAndVersion(orgKey, applicationKey, versionName) @@ -163,7 +165,7 @@ class Versions @Inject() ( } - def postWatch(orgKey: String, applicationKey: String, versionName: String) = IdentifiedOrg.async { implicit request => + def postWatch(orgKey: String, applicationKey: String, versionName: String): Action[AnyContent] = IdentifiedOrg.async { implicit request => apiClientProvider.callWith404( request.api.versions.getByApplicationKeyAndVersion(request.org.key, applicationKey, versionName) ).flatMap { @@ -209,7 +211,7 @@ class Versions @Inject() ( def create( orgKey: String, applicationKey: Option[String] = None - ) = IdentifiedOrg.async { implicit request => + ): Action[AnyContent] = IdentifiedOrg.async { implicit request => request.withMember { applicationKey match { @@ -261,7 +263,7 @@ class Versions @Inject() ( def createPost( orgKey: String, applicationKey: Option[String] = None - ) = IdentifiedOrg.async(parse.multipartFormData) { implicit request => + ): Action[MultipartFormData[Files.TemporaryFile]] = IdentifiedOrg.async(parse.multipartFormData) { implicit request => request.withMember { val tpl = applicationKey match { case None => request.mainTemplate(Some(Labels.AddApplicationText)) @@ -360,6 +362,12 @@ object Versions { originalType: Option[String] ) + object UploadData { + def unapply(d: UploadData): Option[(String, String, Option[String])] = { + Some((d.version, d.visibility, d.originalType)) + } + } + private[controllers] val uploadForm = Form( mapping( "version" -> nonEmptyText, diff --git a/app/app/lib/MemberDownload.scala b/app/app/lib/MemberDownload.scala index e7143b87f..e7c6fb0b4 100644 --- a/app/app/lib/MemberDownload.scala +++ b/app/app/lib/MemberDownload.scala @@ -1,12 +1,13 @@ package lib -import com.github.tototoshi.csv.CSVWriter -import java.io.File +import com.github.tototoshi.csv.{CSVFormat, CSVWriter} +import com.github.tototoshi.csv.defaultCSVFormat +import java.io.File import io.apibuilder.api.v0.models.Membership import scala.concurrent.{Await, ExecutionContext, Future} -import scala.concurrent.duration._ +import scala.concurrent.duration.* case class MemberDownload( client: io.apibuilder.api.v0.Client, @@ -16,7 +17,7 @@ case class MemberDownload( def csv()(implicit ec: ExecutionContext): Future[File] = Future { val file = File.createTempFile(s"member-download-$orgKey", "csv") - val writer = CSVWriter.open(file) + val writer = CSVWriter.open(file)(defaultCSVFormat) writer.writeRow(Seq("guid", "role", "user_guid", "user_email", "user_nickname", "user_name")) Pager.eachPage[Membership] { offset => diff --git a/app/app/views/attributes/create.scala.html b/app/app/views/attributes/create.scala.html index f70d00d82..61d8956f3 100644 --- a/app/app/views/attributes/create.scala.html +++ b/app/app/views/attributes/create.scala.html @@ -7,7 +7,7 @@
- @helper.form(action = routes.AttributesController.createPost) { + @helper.form(action = routes.AttributesController.createPost()) { @attributeForm(form, routes.AttributesController.index()) diff --git a/app/app/views/doc/releaseNotes.scala.html b/app/app/views/doc/releaseNotes.scala.html index e4959a9d0..99203bdd0 100644 --- a/app/app/views/doc/releaseNotes.scala.html +++ b/app/app/views/doc/releaseNotes.scala.html @@ -5,6 +5,32 @@ @doc.main(routes.DocController.releaseNotes.url, user, Some("Release notes")) { +

Jul 10, 2024

+ + + +

Oct 12, 2023

+ + + +

Nov 14, 2022

+ + +

Oct 11, 2021

-

After logging in, Create +

After logging in, Create an organization. The organization will serve as a container for all of your services.

diff --git a/app/app/views/generators/create.scala.html b/app/app/views/generators/create.scala.html index 147a734d2..ed77d9617 100644 --- a/app/app/views/generators/create.scala.html +++ b/app/app/views/generators/create.scala.html @@ -7,7 +7,7 @@
- @helper.form(action = routes.Generators.createPost) { + @helper.form(action = routes.Generators.createPost()) { @generatorForm(form, routes.Generators.index()) diff --git a/app/app/views/index.scala.html b/app/app/views/index.scala.html index 77582f901..36a9c9127 100644 --- a/app/app/views/index.scala.html +++ b/app/app/views/index.scala.html @@ -23,7 +23,7 @@

New to API Builder?

} else { @if(organizations.isEmpty) { diff --git a/app/app/views/login/legacy.scala.html b/app/app/views/login/legacy.scala.html index 12269b85a..a10ef1c4f 100644 --- a/app/app/views/login/legacy.scala.html +++ b/app/app/views/login/legacy.scala.html @@ -32,7 +32,7 @@
- @helper.form(action = routes.LoginController.legacyPost) { + @helper.form(action = routes.LoginController.legacyPost()) { @loginForm.globalErrors.map(_.message).map { msg => @@ -56,7 +56,7 @@ - + } diff --git a/app/app/views/main.scala.html b/app/app/views/main.scala.html index 587ae5938..84d8c3fe5 100644 --- a/app/app/views/main.scala.html +++ b/app/app/views/main.scala.html @@ -70,8 +70,8 @@ @if(!service.enums.isEmpty) { Enums } diff --git a/app/app/views/tokens/index.scala.html b/app/app/views/tokens/index.scala.html index 23042f148..ebfd5ce49 100644 --- a/app/app/views/tokens/index.scala.html +++ b/app/app/views/tokens/index.scala.html @@ -5,7 +5,7 @@ @main(tpl) { @@ -41,7 +41,7 @@

- More information on using API Tokens + More information on using API Tokens

} diff --git a/app/app/views/versions/form.scala.html b/app/app/views/versions/form.scala.html index eac937084..719946ae4 100644 --- a/app/app/views/versions/form.scala.html +++ b/app/app/views/versions/form.scala.html @@ -50,14 +50,14 @@ @helper.select( form("original_type"), - Seq( ("", "-- auto detect --") ) ++ io.apibuilder.api.v0.models.OriginalType.all.map { t => - t match { - case io.apibuilder.api.v0.models.OriginalType.AvroIdl => (t.toString, "Avro IDL (experimental)") - case io.apibuilder.api.v0.models.OriginalType.ApiJson => (t.toString, "api.json") - case io.apibuilder.api.v0.models.OriginalType.ServiceJson => (t.toString, "service.json") - case io.apibuilder.api.v0.models.OriginalType.Swagger => (t.toString, "Swagger: JSON or YAML (2.0, experimental)") - case io.apibuilder.api.v0.models.OriginalType.UNDEFINED(name) => (t.toString, name) - } + Seq( ("", "-- auto detect --") ) ++ io.apibuilder.api.v0.models.OriginalType.all.map { t => + t match { + case io.apibuilder.api.v0.models.OriginalType.AvroIdl => (t.toString, "Avro IDL (experimental)") + case io.apibuilder.api.v0.models.OriginalType.ApiJson => (t.toString, "api.json") + case io.apibuilder.api.v0.models.OriginalType.ServiceJson => (t.toString, "service.json") + case io.apibuilder.api.v0.models.OriginalType.Swagger => (t.toString, "Swagger: JSON or YAML (2.0, experimental)") + case io.apibuilder.api.v0.models.OriginalType.UNDEFINED(name) => (t.toString, name) + } }, Symbol("_label") -> "Type" ) diff --git a/app/app/views/versions/show.scala.html b/app/app/views/versions/show.scala.html index af1075e94..4778272b4 100644 --- a/app/app/views/versions/show.scala.html +++ b/app/app/views/versions/show.scala.html @@ -78,16 +78,16 @@

Enums

@if(service.enums.isEmpty) { No enums } else { - @service.enums.map { enum => -
- + @service.enums.map { e => +
+
-

@enum.name

- @enum.deprecation.map(deprecation(_)) +

@e.name

+ @e.deprecation.map(deprecation(_)) - @Html(lib.Markdown(enum.description)) + @Html(lib.Markdown(e.description)) - @values(tpl.org.get, application, tpl.version.get, enum) + @values(tpl.org.get, application, tpl.version.get, e)
} } diff --git a/app/app/views/versions/values.scala.html b/app/app/views/versions/values.scala.html index 83de90520..665088e4f 100644 --- a/app/app/views/versions/values.scala.html +++ b/app/app/views/versions/values.scala.html @@ -1,7 +1,7 @@ @(org: io.apibuilder.api.v0.models.Organization, app: io.apibuilder.api.v0.models.Application, version: String, - enum: io.apibuilder.spec.v0.models.Enum) + e: io.apibuilder.spec.v0.models.Enum)
@@ -12,15 +12,16 @@ - @enum.values.map { value => + @e.deprecation.map { depr => + + + + } + @e.values.map { value => - + } diff --git a/app/conf/routes b/app/conf/routes index 4e09c9f7f..928473c96 100644 --- a/app/conf/routes +++ b/app/conf/routes @@ -6,8 +6,8 @@ GET /login controllers.Lo GET /login/ controllers.LoginController.index(return_url: Option[String] ?= None) GET /login/dev controllers.LoginController.developmentLogin GET /login/legacy controllers.LoginController.legacy(return_url: Option[String] ?= None) -POST /login/legacy controllers.LoginController.legacyPost -GET /login/forgotPassword controllers.LoginController.forgotPassword +POST /login/legacy controllers.LoginController.legacyPost() +GET /login/forgotPassword controllers.LoginController.forgotPassword() POST /login/forgotPassword controllers.LoginController.postForgotPassword GET /login/resetPassword/:token controllers.LoginController.resetPassword(token: String) POST /login/resetPassword/:token controllers.LoginController.postResetPassword(token: String) @@ -64,13 +64,13 @@ GET /tokens controllers.To GET /tokens/ controllers.TokensController.index(page: Int ?= 0) GET /tokens/show/:guid controllers.TokensController.show(guid: java.util.UUID) GET /tokens/cleartext/:guid controllers.TokensController.cleartext(guid: java.util.UUID) -GET /tokens/create controllers.TokensController.create +GET /tokens/create controllers.TokensController.create() POST /tokens/postCreate controllers.TokensController.postCreate POST /tokens/postDelete/:guid controllers.TokensController.postDelete(guid: java.util.UUID) GET /assets/*file controllers.Assets.at(path="/public", file) -GET /org/create controllers.Organizations.create +GET /org/create controllers.Organizations.create() POST /org/createPost controllers.Organizations.createPost GET /org/edit controllers.Organizations.edit(org_key: String) POST /org/editPost controllers.Organizations.editPost(org_key: String) diff --git a/avro/src/test/scala/io/apibuilder/avro/ParserSpec.scala b/avro/src/test/scala/io/apibuilder/avro/ParserSpec.scala index cb44805a5..45f132fb4 100644 --- a/avro/src/test/scala/io/apibuilder/avro/ParserSpec.scala +++ b/avro/src/test/scala/io/apibuilder/avro/ParserSpec.scala @@ -26,9 +26,9 @@ class ParserSpec extends AnyFunSpec with Matchers { println("namespace: " + service.namespace) println("Enums:") - service.enums.foreach { enum => - println(s" - ${enum.name}") - enum.values.foreach { value => + service.enums.foreach { e => + println(s" - ${e.name}") + e.values.foreach { value => println(s" - ${value.name}") } } diff --git a/build.sbt b/build.sbt index 1cb0deebc..cf84f70ec 100644 --- a/build.sbt +++ b/build.sbt @@ -1,43 +1,42 @@ -import play.sbt.PlayScala._ - name := "apibuilder" - organization := "io.apibuilder" -ThisBuild / scalaVersion := "2.13.14" +ThisBuild / scalaVersion := "3.4.2" -//ThisBuild / javacOptions ++= Seq("-source", "17", "-target", "17") +val playJsonVersion = "2.10.6" + +val avroVersion = "1.11.1" lazy val allScalacOptions = Seq( - "-deprecation", - "-feature", - "-Xfatal-warnings", - "-unchecked", - "-Xcheckinit", - "-Xlint:adapted-args", - "-Ypatmat-exhaust-depth", "100", // Fixes: Exhaustivity analysis reached max recursion depth, not all missing cases are reported. - "-Wconf:src=generated/.*:silent", - "-Wconf:src=target/.*:silent", // silence the unused imports errors generated by the Play Routes + "-feature" +) + +lazy val resolversSettings = Seq( + resolvers += "Typesafe repository" at "https://repo.typesafe.com/typesafe/releases/", + resolvers += "scalaz-bintray" at "https://dl.bintray.com/scalaz/releases", + resolvers += "jitpack" at "https://jitpack.io", ) lazy val lib = project .in(file("lib")) - .settings(commonSettings: _*) - -val avroVersion = "1.11.1" - -val playJsonVersion = "2.10.6" + .settings(commonSettings*) + .settings(resolversSettings) + .settings( + libraryDependencies ++= Seq( + "com.typesafe.play" %% "play-json" % playJsonVersion, + "joda-time" % "joda-time" % "2.12.7", + ) + ) lazy val avro = project .in(file("avro")) - .dependsOn(generated, lib % "compile->compile;test->test") - .aggregate(generated, lib) + .dependsOn(lib % "compile->compile;test->test") + .aggregate(lib) .settings( scalacOptions ++= allScalacOptions, libraryDependencies ++= Seq( "org.apache.avro" % "avro" % avroVersion, "org.apache.avro" % "avro-compiler" % avroVersion, - "com.typesafe.play" %% "play-json" % playJsonVersion, "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.1" % Test ), Test / javaOptions ++= Seq( @@ -48,13 +47,12 @@ lazy val avro = project lazy val swagger = project .in(file("swagger")) - .dependsOn(generated, lib % "compile->compile;test->test") - .aggregate(generated, lib) + .dependsOn(lib % "compile->compile;test->test") + .aggregate(lib) .settings( scalacOptions ++= allScalacOptions, libraryDependencies ++= Seq( "io.swagger" % "swagger-parser" % "1.0.61", - "com.typesafe.play" %% "play-json" % playJsonVersion, "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.1" % Test ), Test / javaOptions ++= Seq( @@ -63,29 +61,33 @@ lazy val swagger = project ) ) -val circeVersion = "0.14.8" +val circeVersion = "0.14.9" lazy val core = project .in(file("core")) + .enablePlugins(PlayScala) .dependsOn(generated, lib, avro, swagger) - .aggregate(generated, lib) - .settings(commonSettings: _*) + .aggregate(generated, lib, avro, swagger) + .settings(commonSettings*) .settings( - resolvers += "Typesafe Maven Repository" at "https://repo.typesafe.com/typesafe/maven-releases/", libraryDependencies ++= Seq( - "com.typesafe.play" %% "play-json" % playJsonVersion, "io.circe" %% "circe-core" % circeVersion, "io.circe" %% "circe-generic" % circeVersion, "io.circe" %% "circe-parser" % circeVersion - ) + ), ) lazy val generated = project .in(file("generated")) .enablePlugins(PlayScala) - .settings(commonSettings: _*) + .settings(commonSettings*) .settings( + scalacOptions ++= Seq("-deprecation:false"), libraryDependencies ++= Seq( - ws + ws, + "joda-time" % "joda-time" % "2.12.7", + "org.playframework.anorm" %% "anorm-postgres" % "2.7.0", + "org.postgresql" % "postgresql" % "42.7.3", + "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.1" % Test, ) ) @@ -94,8 +96,9 @@ lazy val api = project .dependsOn(generated, core % "compile->compile;test->test") .aggregate(generated, core) .enablePlugins(PlayScala, JavaAgent) - .settings(commonSettings: _*) + .settings(commonSettings*) .settings( + scalacOptions ++= Seq("-deprecation:false"), scalacOptions ++= allScalacOptions, PlayKeys.fileWatchService := play.dev.filewatch.FileWatchService.jdk7(play.sbt.run.toLoggerProxy(sLog.value)), testOptions += Tests.Argument("-oF"), @@ -104,21 +107,19 @@ lazy val api = project routesImport += "io.apibuilder.api.v0.Bindables.Models._", routesImport += "io.apibuilder.common.v0.Bindables.Models._", routesGenerator := InjectedRoutesGenerator, - resolvers += "Scalaz Bintray Repo" at "https://dl.bintray.com/scalaz/releases", - resolvers += "Artifactory" at "https://flow.jfrog.io/flow/libs-release", libraryDependencies ++= Seq( filters, jdbc, ws, + "com.typesafe.play" %% "play-guice" % "2.9.4", "com.google.inject" % "guice" % "5.1.0", "com.google.inject.extensions" % "guice-assistedinject" % "5.1.0", "org.projectlombok" % "lombok" % "1.18.32" % "provided", - "com.typesafe.play" %% "play-json-joda" % playJsonVersion, - "com.typesafe.play" %% "play-json" % playJsonVersion, - "org.postgresql" % "postgresql" % "42.7.3", - "org.mindrot" % "jbcrypt" % "0.4", + ("com.github.mbryzek" % "lib-cipher" % "0.0.2").cross(CrossVersion.for3Use2_13), + "com.github.mbryzek" % "lib-util" % "0.0.7", "com.sendgrid" % "sendgrid-java" % "4.10.2", - "io.flow" %% "lib-postgresql-play-play28" % "0.5.53", + "com.github.mbryzek" % "lib-query" % "0.0.2", + "com.rollbar" % "rollbar-java" % "1.10.0", "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.1" % Test, "com.github.tomakehurst" % "wiremock-standalone" % "3.0.1" % Test ), @@ -135,7 +136,7 @@ lazy val app = project .dependsOn(generated, lib) .aggregate(generated, lib) .enablePlugins(PlayScala, JavaAgent, SbtTwirl) - .settings(commonSettings: _*) + .settings(commonSettings*) .settings( scalacOptions ++= allScalacOptions, PlayKeys.fileWatchService := play.dev.filewatch.FileWatchService.jdk7(play.sbt.run.toLoggerProxy(sLog.value)), @@ -149,12 +150,10 @@ lazy val app = project "com.google.inject" % "guice" % "5.1.0", "com.google.inject.extensions" % "guice-assistedinject" % "5.1.0", "org.projectlombok" % "lombok" % "1.18.28" % "provided", - "com.typesafe.play" %% "play-json-joda" % playJsonVersion, - "com.typesafe.play" %% "play-json" % playJsonVersion, "org.apache.commons" % "commons-compress" % "1.26.2", "com.github.tototoshi" %% "scala-csv" % "1.4.0", "com.vladsch.flexmark" % "flexmark-all" % "0.64.8", - "org.webjars" %% "webjars-play" % "2.8.18", + "org.webjars" %% "webjars-play" % "3.0.1", "org.webjars" % "bootstrap" % "3.3.7", "org.webjars" % "bootstrap-social" % "5.0.0", "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.1" % Test @@ -182,11 +181,8 @@ lazy val commonSettings: Seq[Setting[_]] = Seq( name ~= ("apibuilder-" + _), organization := "io.apibuilder", libraryDependencies ++= Seq( - "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.17.1", - "com.typesafe.play" %% "play-json-joda" % playJsonVersion, "org.atteo" % "evo-inflector" % "1.3", "org.typelevel" %% "cats-core" % "2.12.0", - "org.slf4j" % "slf4j-api" % "2.0.13", "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.1" % Test ), scalacOptions ++= allScalacOptions, diff --git a/core/src/main/scala/core/DuplicateJsonParser.scala b/core/app/DuplicateJsonParser.scala similarity index 100% rename from core/src/main/scala/core/DuplicateJsonParser.scala rename to core/app/DuplicateJsonParser.scala diff --git a/core/src/main/scala/core/Importer.scala b/core/app/Importer.scala similarity index 100% rename from core/src/main/scala/core/Importer.scala rename to core/app/Importer.scala diff --git a/core/src/main/scala/core/ServiceFetcher.scala b/core/app/ServiceFetcher.scala similarity index 100% rename from core/src/main/scala/core/ServiceFetcher.scala rename to core/app/ServiceFetcher.scala diff --git a/core/src/main/scala/core/TypeValidator.scala b/core/app/TypeValidator.scala similarity index 97% rename from core/src/main/scala/core/TypeValidator.scala rename to core/app/TypeValidator.scala index 5866f1fbb..caf5a0ec5 100644 --- a/core/src/main/scala/core/TypeValidator.scala +++ b/core/app/TypeValidator.scala @@ -102,12 +102,12 @@ object TypesProvider { case class FromService(service: Service) extends TypesProvider { - override def enums: Iterable[TypesProviderEnum] = service.enums.map { enum => + override def enums: Iterable[TypesProviderEnum] = service.enums.map { e => TypesProviderEnum( namespace = service.namespace, - name = enum.name, - plural = enum.plural, - values = enum.values.map(_.name) + name = e.name, + plural = e.plural, + values = e.values.map(_.name) ) } @@ -237,13 +237,13 @@ case class TypeValidator( None } - case Some(enum) => { - enum.values.find(_ == value) match { + case Some(e) => { + e.values.find(_ == value) match { case None => { Some( withPrefix( errorPrefix, - s"default[$value] is not a valid value for enum[$name]. Valid values are: " + enum.values.mkString(", ") + s"default[$value] is not a valid value for enum[$name]. Valid values are: " + e.values.mkString(", ") ) ) } diff --git a/core/src/main/scala/core/Util.scala b/core/app/Util.scala similarity index 100% rename from core/src/main/scala/core/Util.scala rename to core/app/Util.scala diff --git a/core/src/main/scala/core/VersionMigration.scala b/core/app/VersionMigration.scala similarity index 100% rename from core/src/main/scala/core/VersionMigration.scala rename to core/app/VersionMigration.scala diff --git a/core/src/main/scala/core/builder/DuplicateErrorMessage.scala b/core/app/builder/DuplicateErrorMessage.scala similarity index 100% rename from core/src/main/scala/core/builder/DuplicateErrorMessage.scala rename to core/app/builder/DuplicateErrorMessage.scala diff --git a/core/src/main/scala/core/builder/JsonUtil.scala b/core/app/builder/JsonUtil.scala similarity index 100% rename from core/src/main/scala/core/builder/JsonUtil.scala rename to core/app/builder/JsonUtil.scala diff --git a/core/src/main/scala/core/builder/OriginalValidator.scala b/core/app/builder/OriginalValidator.scala similarity index 100% rename from core/src/main/scala/core/builder/OriginalValidator.scala rename to core/app/builder/OriginalValidator.scala diff --git a/core/src/main/scala/core/builder/ServiceSpecValidator.scala b/core/app/builder/ServiceSpecValidator.scala similarity index 97% rename from core/src/main/scala/core/builder/ServiceSpecValidator.scala rename to core/app/builder/ServiceSpecValidator.scala index 321146e4d..8d90cda03 100644 --- a/core/src/main/scala/core/builder/ServiceSpecValidator.scala +++ b/core/app/builder/ServiceSpecValidator.scala @@ -19,8 +19,8 @@ case class ServiceSpecValidator( private val typeResolver = DatatypeResolver( enumNames = localTypeResolver.enumNames ++ service.imports.flatMap { service => - service.enums.map { enum => - s"${service.namespace}.enums.$enum" + service.enums.map { e => + s"${service.namespace}.enums.$e" } }, @@ -150,7 +150,7 @@ case class ServiceSpecValidator( ) } - def validateField(prefix: String, field: Field): ValidatedNec[String, Unit] = { + private def validateField(prefix: String, field: Field): ValidatedNec[String, Unit] = { sequenceUnique( Seq( validateName(s"$prefix name", field.name), @@ -226,8 +226,8 @@ case class ServiceSpecValidator( private def validateEnumNames(): ValidatedNec[String, Unit] = { sequenceUnique( - service.enums.map { enum => - validateName(s"Enum[${enum.name}] name", enum.name) + service.enums.map { e => + validateName(s"Enum[${e.name}] name", e.name) } ++ Seq( DuplicateErrorMessage.validate("Enum", service.enums.map(_.name)) ) @@ -235,12 +235,12 @@ case class ServiceSpecValidator( } private def validateEnumValues(): ValidatedNec[String, Unit] = { sequenceUnique ( - service.enums.filter(_.name.nonEmpty).flatMap { enum => - (if (enum.values.isEmpty) { - Seq(s"Enum[${enum.name}] must have at least one value".invalidNec) + service.enums.filter(_.name.nonEmpty).flatMap { e => + (if (e.values.isEmpty) { + Seq(s"Enum[${e.name}] must have at least one value".invalidNec) } else { - enum.values.map { value => - validateName(s"Enum[${enum.name}] name[${value.name}]", value.name) + e.values.map { value => + validateName(s"Enum[${e.name}] name[${value.name}]", value.name) } }) ++ Seq(validateEnumValuesUniqueness()) } @@ -249,11 +249,11 @@ case class ServiceSpecValidator( private def validateEnumValuesUniqueness(): ValidatedNec[String, Unit] = { sequenceUnique( - service.enums.map { enum => - DuplicateErrorMessage.validate(s"Enum[${enum.name}] value", enum.values.map(_.name)) - } ++ service.enums.map { enum => + service.enums.map { e => + DuplicateErrorMessage.validate(s"Enum[${e.name}] value", e.values.map(_.name)) + } ++ service.enums.map { e => // Check uniqueness of the serialization values - DuplicateErrorMessage.validate(s"Enum[${enum.name}] value", enum.values.map { ev => ev.value.getOrElse(ev.name) }) + DuplicateErrorMessage.validate(s"Enum[${e.name}] value", e.values.map { ev => ev.value.getOrElse(ev.name) }) } ) } diff --git a/core/src/main/scala/core/builder/api_json/ApiJsonServiceValidator.scala b/core/app/builder/api_json/ApiJsonServiceValidator.scala similarity index 99% rename from core/src/main/scala/core/builder/api_json/ApiJsonServiceValidator.scala rename to core/app/builder/api_json/ApiJsonServiceValidator.scala index e4b4d8f39..1557e6c89 100644 --- a/core/src/main/scala/core/builder/api_json/ApiJsonServiceValidator.scala +++ b/core/app/builder/api_json/ApiJsonServiceValidator.scala @@ -155,8 +155,8 @@ case class ApiJsonServiceValidator( private def validateEnums(enums: Seq[InternalEnumForm]): ValidatedNec[String, Unit] = { sequenceUnique( - enums.map(_.warnings) ++ enums.map { enum => - validateAttributes(s"Enum[${enum.name}]", enum.attributes) + enums.map(_.warnings) ++ enums.map { e => + validateAttributes(s"Enum[${e.name}]", e.attributes) } ++ enums.map(validateEnumValues) ) } diff --git a/core/src/main/scala/core/builder/api_json/InternalApiJsonForm.scala b/core/app/builder/api_json/InternalApiJsonForm.scala similarity index 99% rename from core/src/main/scala/core/builder/api_json/InternalApiJsonForm.scala rename to core/app/builder/api_json/InternalApiJsonForm.scala index 291c3894b..8cf9ca4f6 100644 --- a/core/src/main/scala/core/builder/api_json/InternalApiJsonForm.scala +++ b/core/app/builder/api_json/InternalApiJsonForm.scala @@ -664,7 +664,7 @@ object InternalResourceForm extends ValidatedHelpers { } case None => { enums.find(e => e.name == typeName) match { - case Some(enum) => Some("/" + enum.plural) + case Some(e) => Some("/" + e.plural) case None => { models.find(m => m.name == typeName) match { case Some(model) => Some("/" + model.plural) diff --git a/core/src/main/scala/core/builder/api_json/InternalDatatype.scala b/core/app/builder/api_json/InternalDatatype.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/InternalDatatype.scala rename to core/app/builder/api_json/InternalDatatype.scala diff --git a/core/src/main/scala/core/builder/api_json/ServiceBuilder.scala b/core/app/builder/api_json/ServiceBuilder.scala similarity index 98% rename from core/src/main/scala/core/builder/api_json/ServiceBuilder.scala rename to core/app/builder/api_json/ServiceBuilder.scala index 690c74b45..5177e0adc 100644 --- a/core/src/main/scala/core/builder/api_json/ServiceBuilder.scala +++ b/core/app/builder/api_json/ServiceBuilder.scala @@ -95,8 +95,8 @@ case class ServiceBuilder( name: String ): Resolution = { resolver.enums.find(o => o.name == name || o.fullName == name) match { - case Some(enum) => { - Resolution(enum = Some(enum)) + case Some(e) => { + Resolution(`enum` = Some(e)) } case None => { resolver.models.find(o => o.name == name || o.fullName == name) match { @@ -124,12 +124,12 @@ case class ServiceBuilder( ): Resource = { val resolution = resolve(resolver.provider, internal.datatype.name) - resolution.enum match { - case Some(enum) => { - val resourcePath = internal.path.getOrElse("/" + enum.plural) + resolution.`enum` match { + case Some(e) => { + val resourcePath = internal.path.getOrElse("/" + e.plural) Resource( `type` = internal.datatype.label, - plural = enum.plural, + plural = e.plural, path = Some(resourcePath), description = internal.description, deprecation = internal.deprecation.map(DeprecationBuilder(_)), diff --git a/core/src/main/scala/core/builder/api_json/ServiceJsonServiceValidator.scala b/core/app/builder/api_json/ServiceJsonServiceValidator.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/ServiceJsonServiceValidator.scala rename to core/app/builder/api_json/ServiceJsonServiceValidator.scala diff --git a/core/src/main/scala/core/builder/api_json/Types.scala b/core/app/builder/api_json/Types.scala similarity index 96% rename from core/src/main/scala/core/builder/api_json/Types.scala rename to core/app/builder/api_json/Types.scala index b964cc40c..7fff4dd4a 100644 --- a/core/src/main/scala/core/builder/api_json/Types.scala +++ b/core/app/builder/api_json/Types.scala @@ -6,12 +6,12 @@ import lib.Kind private[api_json] case class InternalApiJsonFormTypesProvider(internal: InternalApiJsonForm) extends TypesProvider { - override def enums: Seq[TypesProviderEnum] = internal.enums.map { enum => + override def enums: Seq[TypesProviderEnum] = internal.enums.map { e => TypesProviderEnum( namespace = internal.namespace.getOrElse(""), - name = enum.name, - plural = enum.plural, - values = enum.values.flatMap(_.name) + name = e.name, + plural = e.plural, + values = e.values.flatMap(_.name) ) } @@ -21,7 +21,7 @@ private[api_json] case class InternalApiJsonFormTypesProvider(internal: Internal name = u.name, plural = u.plural, types = u.types.flatMap { t => - t.datatype.toOption.map(_.name).map(core.TypesProviderUnionType) + t.datatype.toOption.map(_.name).map(core.TypesProviderUnionType(_)) } ) } diff --git a/core/src/main/scala/core/builder/api_json/templates/ArrayMerge.scala b/core/app/builder/api_json/templates/ArrayMerge.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/templates/ArrayMerge.scala rename to core/app/builder/api_json/templates/ArrayMerge.scala diff --git a/core/src/main/scala/core/builder/api_json/templates/AttributeMerge.scala b/core/app/builder/api_json/templates/AttributeMerge.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/templates/AttributeMerge.scala rename to core/app/builder/api_json/templates/AttributeMerge.scala diff --git a/core/src/main/scala/core/builder/api_json/templates/HeaderMerge.scala b/core/app/builder/api_json/templates/HeaderMerge.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/templates/HeaderMerge.scala rename to core/app/builder/api_json/templates/HeaderMerge.scala diff --git a/core/src/main/scala/core/builder/api_json/templates/JsMerge.scala b/core/app/builder/api_json/templates/JsMerge.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/templates/JsMerge.scala rename to core/app/builder/api_json/templates/JsMerge.scala diff --git a/core/src/main/scala/core/builder/api_json/templates/MapMerge.scala b/core/app/builder/api_json/templates/MapMerge.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/templates/MapMerge.scala rename to core/app/builder/api_json/templates/MapMerge.scala diff --git a/core/src/main/scala/core/builder/api_json/templates/ModelMerge.scala b/core/app/builder/api_json/templates/ModelMerge.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/templates/ModelMerge.scala rename to core/app/builder/api_json/templates/ModelMerge.scala diff --git a/core/src/main/scala/core/builder/api_json/templates/OptionHelpers.scala b/core/app/builder/api_json/templates/OptionHelpers.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/templates/OptionHelpers.scala rename to core/app/builder/api_json/templates/OptionHelpers.scala diff --git a/core/src/main/scala/core/builder/api_json/templates/RenameTypes.scala b/core/app/builder/api_json/templates/RenameTypes.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/templates/RenameTypes.scala rename to core/app/builder/api_json/templates/RenameTypes.scala diff --git a/core/src/main/scala/core/builder/api_json/templates/ResourceMerge.scala b/core/app/builder/api_json/templates/ResourceMerge.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/templates/ResourceMerge.scala rename to core/app/builder/api_json/templates/ResourceMerge.scala diff --git a/core/src/main/scala/core/builder/api_json/templates/TemplateMerge.scala b/core/app/builder/api_json/templates/TemplateMerge.scala similarity index 97% rename from core/src/main/scala/core/builder/api_json/templates/TemplateMerge.scala rename to core/app/builder/api_json/templates/TemplateMerge.scala index 30147ce66..5e876d0d1 100644 --- a/core/src/main/scala/core/builder/api_json/templates/TemplateMerge.scala +++ b/core/app/builder/api_json/templates/TemplateMerge.scala @@ -66,7 +66,7 @@ private[templates] abstract class TemplateMerge[T](templates: Map[String, T]) { remaining.toList match { case Nil if first.isEmpty => None case Nil => Some(first) - case one :: rest => union((first ++ one).distinct, rest: _*) + case one :: rest => union((first ++ one).distinct, rest*) } } } diff --git a/core/src/main/scala/core/builder/api_json/upgrades/InterfacesToSupportResources.scala b/core/app/builder/api_json/upgrades/InterfacesToSupportResources.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/upgrades/InterfacesToSupportResources.scala rename to core/app/builder/api_json/upgrades/InterfacesToSupportResources.scala diff --git a/core/src/main/scala/core/builder/api_json/upgrades/RemoveApiDocElement.scala b/core/app/builder/api_json/upgrades/RemoveApiDocElement.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/upgrades/RemoveApiDocElement.scala rename to core/app/builder/api_json/upgrades/RemoveApiDocElement.scala diff --git a/core/src/main/scala/core/builder/api_json/upgrades/ServiceParser.scala b/core/app/builder/api_json/upgrades/ServiceParser.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/upgrades/ServiceParser.scala rename to core/app/builder/api_json/upgrades/ServiceParser.scala diff --git a/core/src/main/scala/core/builder/api_json/upgrades/Upgrader.scala b/core/app/builder/api_json/upgrades/Upgrader.scala similarity index 100% rename from core/src/main/scala/core/builder/api_json/upgrades/Upgrader.scala rename to core/app/builder/api_json/upgrades/Upgrader.scala diff --git a/core/src/main/scala/core/generated/ApicollectiveApibuilderApiJsonV0Models.scala b/core/app/generated/ApicollectiveApibuilderApiJsonV0Models.scala similarity index 99% rename from core/src/main/scala/core/generated/ApicollectiveApibuilderApiJsonV0Models.scala rename to core/app/generated/ApicollectiveApibuilderApiJsonV0Models.scala index 1dfb416d6..82263dd9b 100644 --- a/core/src/main/scala/core/generated/ApicollectiveApibuilderApiJsonV0Models.scala +++ b/core/app/generated/ApicollectiveApibuilderApiJsonV0Models.scala @@ -1,7 +1,7 @@ /** * Generated by API Builder - https://www.apibuilder.io - * Service version: 0.16.48 - * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-api-json/latest/play_2_x_json + * Service version: 0.16.50 + * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-api-json/latest/play_2_x_scala_3_json */ package io.apibuilder.api.json.v0.models { diff --git a/core/src/test/scala/core/ApiJsonStructureSpec.scala b/core/test/core/ApiJsonStructureSpec.scala similarity index 100% rename from core/src/test/scala/core/ApiJsonStructureSpec.scala rename to core/test/core/ApiJsonStructureSpec.scala diff --git a/core/src/test/scala/core/BodyParameterSpec.scala b/core/test/core/BodyParameterSpec.scala similarity index 100% rename from core/src/test/scala/core/BodyParameterSpec.scala rename to core/test/core/BodyParameterSpec.scala diff --git a/core/src/test/scala/core/BrokenSpec.scala b/core/test/core/BrokenSpec.scala similarity index 100% rename from core/src/test/scala/core/BrokenSpec.scala rename to core/test/core/BrokenSpec.scala diff --git a/core/src/test/scala/core/DeprecationSpec.scala b/core/test/core/DeprecationSpec.scala similarity index 100% rename from core/src/test/scala/core/DeprecationSpec.scala rename to core/test/core/DeprecationSpec.scala diff --git a/core/src/test/scala/core/DuplicateFieldValidatorSpec.scala b/core/test/core/DuplicateFieldValidatorSpec.scala similarity index 100% rename from core/src/test/scala/core/DuplicateFieldValidatorSpec.scala rename to core/test/core/DuplicateFieldValidatorSpec.scala diff --git a/core/src/test/scala/core/DuplicateNamesSpec.scala b/core/test/core/DuplicateNamesSpec.scala similarity index 100% rename from core/src/test/scala/core/DuplicateNamesSpec.scala rename to core/test/core/DuplicateNamesSpec.scala diff --git a/core/src/test/scala/core/EnumSpec.scala b/core/test/core/EnumSpec.scala similarity index 100% rename from core/src/test/scala/core/EnumSpec.scala rename to core/test/core/EnumSpec.scala diff --git a/core/src/test/scala/core/FileServiceFetcher.scala b/core/test/core/FileServiceFetcher.scala similarity index 100% rename from core/src/test/scala/core/FileServiceFetcher.scala rename to core/test/core/FileServiceFetcher.scala diff --git a/core/src/test/scala/core/ImportServiceApiJsonSpec.scala b/core/test/core/ImportServiceApiJsonSpec.scala similarity index 100% rename from core/src/test/scala/core/ImportServiceApiJsonSpec.scala rename to core/test/core/ImportServiceApiJsonSpec.scala diff --git a/core/src/test/scala/core/ImportServiceServiceJsonSpec.scala b/core/test/core/ImportServiceServiceJsonSpec.scala similarity index 100% rename from core/src/test/scala/core/ImportServiceServiceJsonSpec.scala rename to core/test/core/ImportServiceServiceJsonSpec.scala diff --git a/core/src/test/scala/core/ImportedResourcePathsSpec.scala b/core/test/core/ImportedResourcePathsSpec.scala similarity index 100% rename from core/src/test/scala/core/ImportedResourcePathsSpec.scala rename to core/test/core/ImportedResourcePathsSpec.scala diff --git a/core/src/test/scala/core/ImporterSpec.scala b/core/test/core/ImporterSpec.scala similarity index 100% rename from core/src/test/scala/core/ImporterSpec.scala rename to core/test/core/ImporterSpec.scala diff --git a/core/src/test/scala/core/InfoSpec.scala b/core/test/core/InfoSpec.scala similarity index 100% rename from core/src/test/scala/core/InfoSpec.scala rename to core/test/core/InfoSpec.scala diff --git a/core/src/test/scala/core/InlineEnumInModelFieldsSpec.scala b/core/test/core/InlineEnumInModelFieldsSpec.scala similarity index 100% rename from core/src/test/scala/core/InlineEnumInModelFieldsSpec.scala rename to core/test/core/InlineEnumInModelFieldsSpec.scala diff --git a/core/src/test/scala/core/InlineEnumsSpec.scala b/core/test/core/InlineEnumsSpec.scala similarity index 100% rename from core/src/test/scala/core/InlineEnumsSpec.scala rename to core/test/core/InlineEnumsSpec.scala diff --git a/core/src/test/scala/core/InlineModelsSpec.scala b/core/test/core/InlineModelsSpec.scala similarity index 100% rename from core/src/test/scala/core/InlineModelsSpec.scala rename to core/test/core/InlineModelsSpec.scala diff --git a/core/src/test/scala/core/InlineUnionsSpec.scala b/core/test/core/InlineUnionsSpec.scala similarity index 99% rename from core/src/test/scala/core/InlineUnionsSpec.scala rename to core/test/core/InlineUnionsSpec.scala index 6ef3f00ae..2c3a68174 100644 --- a/core/src/test/scala/core/InlineUnionsSpec.scala +++ b/core/test/core/InlineUnionsSpec.scala @@ -6,9 +6,7 @@ import org.scalatest.matchers.should.Matchers class InlineUnionsSpec extends AnyFunSpec with Matchers with ApiJsonHelpers { - - - it("union types support inline models") { + it("union types support inline models") { val json = """ { diff --git a/core/src/test/scala/core/InterfaceImportsSpec.scala b/core/test/core/InterfaceImportsSpec.scala similarity index 100% rename from core/src/test/scala/core/InterfaceImportsSpec.scala rename to core/test/core/InterfaceImportsSpec.scala diff --git a/core/src/test/scala/core/InterfaceSpec.scala b/core/test/core/InterfaceSpec.scala similarity index 100% rename from core/src/test/scala/core/InterfaceSpec.scala rename to core/test/core/InterfaceSpec.scala diff --git a/core/src/test/scala/core/MockServiceFetcher.scala b/core/test/core/MockServiceFetcher.scala similarity index 100% rename from core/src/test/scala/core/MockServiceFetcher.scala rename to core/test/core/MockServiceFetcher.scala diff --git a/core/src/test/scala/core/NestedUnionsSpec.scala b/core/test/core/NestedUnionsSpec.scala similarity index 60% rename from core/src/test/scala/core/NestedUnionsSpec.scala rename to core/test/core/NestedUnionsSpec.scala index 47f673495..3beb1cf04 100644 --- a/core/src/test/scala/core/NestedUnionsSpec.scala +++ b/core/test/core/NestedUnionsSpec.scala @@ -7,45 +7,45 @@ import org.scalatest.matchers.should.Matchers class NestedUnionsSpec extends AnyFunSpec with Matchers with ApiJsonHelpers { - it("validates discriminator values are unique") { - def setup( - userDiscriminatorValue: String, - guestDiscriminatorValue: String, - abstractUserDiscriminatorValue: Option[String], - ) = { - val service = makeApiJson( - models = Map( - "user" -> makeModelWithField(), - "guest" -> makeModelWithField(), + it("validates discriminator values are unique") { + def setup( + userDiscriminatorValue: String, + guestDiscriminatorValue: String, + abstractUserDiscriminatorValue: Option[String], + ) = { + val service = makeApiJson( + models = Map( + "user" -> makeModelWithField(), + "guest" -> makeModelWithField(), + ), + unions = Map( + "abstract_user" -> makeUnion( + types = Seq(makeUnionType("user", discriminatorValue = Some(userDiscriminatorValue))) ), - unions = Map( - "abstract_user" -> makeUnion( - types = Seq(makeUnionType("user", discriminatorValue = Some(userDiscriminatorValue))) - ), - "abstract_guest" -> makeUnion( - types = Seq(makeUnionType("guest", discriminatorValue = Some(guestDiscriminatorValue))) - ), - "party" -> makeUnion( - types = Seq( - makeUnionType("abstract_user", discriminatorValue = abstractUserDiscriminatorValue), - makeUnionType("abstract_guest"), - ) + "abstract_guest" -> makeUnion( + types = Seq(makeUnionType("guest", discriminatorValue = Some(guestDiscriminatorValue))) + ), + "party" -> makeUnion( + types = Seq( + makeUnionType("abstract_user", discriminatorValue = abstractUserDiscriminatorValue), + makeUnionType("abstract_guest"), ) ) ) - TestHelper.serviceValidator(service) match { - case Invalid(e) => e.toNonEmptyList.toList - case Valid(_) => Nil - } + ) + TestHelper.serviceValidator(service) match { + case Invalid(e) => e.toNonEmptyList.toList + case Valid(_) => Nil } + } - setup("user", "guest", None) shouldBe Nil - setup("user", "user", None) shouldBe Seq( - "Union[party] discriminator value[user] appears more than once" - ) - setup("user", "guest", Some("user")) shouldBe Seq( - "Union[party] discriminator value[user] appears more than once" - ) + setup("user", "guest", None) shouldBe Nil + setup("user", "user", None) shouldBe Seq( + "Union[party] discriminator value[user] appears more than once" + ) + setup("user", "guest", Some("user")) shouldBe Seq( + "Union[party] discriminator value[user] appears more than once" + ) } it("share a common discriminator") { diff --git a/core/src/test/scala/core/OriginalValidatorSpec.scala b/core/test/core/OriginalValidatorSpec.scala similarity index 92% rename from core/src/test/scala/core/OriginalValidatorSpec.scala rename to core/test/core/OriginalValidatorSpec.scala index 3d7938416..a5a597cbe 100644 --- a/core/src/test/scala/core/OriginalValidatorSpec.scala +++ b/core/test/core/OriginalValidatorSpec.scala @@ -32,7 +32,7 @@ class OriginalValidatorSpec it("should validate valid swagger json with parameter of type array") { val filename = "simple-w-array.json" - val path = s"core/src/test/resources/$filename" + val path = s"test/resources/$filename" expectValid { validator.validate(readFile(path)) } @@ -40,7 +40,7 @@ class OriginalValidatorSpec it("should validate valid swagger json without parameter of type array") { val filename = "simple-without-array.json" - val path = s"core/src/test/resources/$filename" + val path = s"test/resources/$filename" expectValid { validator.validate(readFile(path)) } diff --git a/core/src/test/scala/core/ServiceAnnotationsSpec.scala b/core/test/core/ServiceAnnotationsSpec.scala similarity index 100% rename from core/src/test/scala/core/ServiceAnnotationsSpec.scala rename to core/test/core/ServiceAnnotationsSpec.scala diff --git a/core/src/test/scala/core/ServiceCommonReturnTypeSpec.scala b/core/test/core/ServiceCommonReturnTypeSpec.scala similarity index 100% rename from core/src/test/scala/core/ServiceCommonReturnTypeSpec.scala rename to core/test/core/ServiceCommonReturnTypeSpec.scala diff --git a/core/src/test/scala/core/ServiceDefaultsSpec.scala b/core/test/core/ServiceDefaultsSpec.scala similarity index 100% rename from core/src/test/scala/core/ServiceDefaultsSpec.scala rename to core/test/core/ServiceDefaultsSpec.scala diff --git a/core/src/test/scala/core/ServiceEnumSpec.scala b/core/test/core/ServiceEnumSpec.scala similarity index 100% rename from core/src/test/scala/core/ServiceEnumSpec.scala rename to core/test/core/ServiceEnumSpec.scala diff --git a/core/src/test/scala/core/ServiceHeaderImportsSpec.scala b/core/test/core/ServiceHeaderImportsSpec.scala similarity index 100% rename from core/src/test/scala/core/ServiceHeaderImportsSpec.scala rename to core/test/core/ServiceHeaderImportsSpec.scala diff --git a/core/src/test/scala/core/ServiceHeadersSpec.scala b/core/test/core/ServiceHeadersSpec.scala similarity index 100% rename from core/src/test/scala/core/ServiceHeadersSpec.scala rename to core/test/core/ServiceHeadersSpec.scala diff --git a/core/src/test/scala/core/ServiceInternalReferencesSpec.scala b/core/test/core/ServiceInternalReferencesSpec.scala similarity index 100% rename from core/src/test/scala/core/ServiceInternalReferencesSpec.scala rename to core/test/core/ServiceInternalReferencesSpec.scala diff --git a/core/src/test/scala/core/ServiceMapSpec.scala b/core/test/core/ServiceMapSpec.scala similarity index 100% rename from core/src/test/scala/core/ServiceMapSpec.scala rename to core/test/core/ServiceMapSpec.scala diff --git a/core/src/test/scala/core/ServiceMethodsSpec.scala b/core/test/core/ServiceMethodsSpec.scala similarity index 100% rename from core/src/test/scala/core/ServiceMethodsSpec.scala rename to core/test/core/ServiceMethodsSpec.scala diff --git a/core/src/test/scala/core/ServiceParametersSpec.scala b/core/test/core/ServiceParametersSpec.scala similarity index 100% rename from core/src/test/scala/core/ServiceParametersSpec.scala rename to core/test/core/ServiceParametersSpec.scala diff --git a/core/src/test/scala/core/ServicePathParametersSpec.scala b/core/test/core/ServicePathParametersSpec.scala similarity index 100% rename from core/src/test/scala/core/ServicePathParametersSpec.scala rename to core/test/core/ServicePathParametersSpec.scala diff --git a/core/src/test/scala/core/ServiceResourcesSpec.scala b/core/test/core/ServiceResourcesSpec.scala similarity index 100% rename from core/src/test/scala/core/ServiceResourcesSpec.scala rename to core/test/core/ServiceResourcesSpec.scala diff --git a/core/src/test/scala/core/ServiceResponsesSpec.scala b/core/test/core/ServiceResponsesSpec.scala similarity index 100% rename from core/src/test/scala/core/ServiceResponsesSpec.scala rename to core/test/core/ServiceResponsesSpec.scala diff --git a/core/src/test/scala/core/ServiceValidatorSpec.scala b/core/test/core/ServiceValidatorSpec.scala similarity index 99% rename from core/src/test/scala/core/ServiceValidatorSpec.scala rename to core/test/core/ServiceValidatorSpec.scala index 8daf55eb1..ebb02bc1f 100644 --- a/core/src/test/scala/core/ServiceValidatorSpec.scala +++ b/core/test/core/ServiceValidatorSpec.scala @@ -484,7 +484,7 @@ class ServiceValidatorSpec extends AnyFunSpec with Matchers with helpers.ApiJson } it("resources with duplicate plural names are NOT allowed") { - val json = + val json = """ { "name": "API Builder", diff --git a/core/src/test/scala/core/SvcApiDocJsonSpec.scala b/core/test/core/SvcApiDocJsonSpec.scala similarity index 100% rename from core/src/test/scala/core/SvcApiDocJsonSpec.scala rename to core/test/core/SvcApiDocJsonSpec.scala diff --git a/core/src/test/scala/core/SvcIrisHubSpec.scala b/core/test/core/SvcIrisHubSpec.scala similarity index 98% rename from core/src/test/scala/core/SvcIrisHubSpec.scala rename to core/test/core/SvcIrisHubSpec.scala index 84386d4df..af87d8e49 100644 --- a/core/src/test/scala/core/SvcIrisHubSpec.scala +++ b/core/test/core/SvcIrisHubSpec.scala @@ -10,7 +10,7 @@ import org.scalatest.matchers.should.Matchers class SvcIrisHubSpec extends AnyFunSpec with Matchers with ValidatedHelpers with ValidatedTestHelpers { private val Filenames: Seq[String] = Seq("svc-iris-hub-0-0-1.json") - private val Dir: String = "core/src/test/resources" + private val Dir: String = "core/test/resources" it("should parse valid json") { Filenames.foreach { name => diff --git a/core/src/test/scala/core/TemplateSpec.scala b/core/test/core/TemplateSpec.scala similarity index 100% rename from core/src/test/scala/core/TemplateSpec.scala rename to core/test/core/TemplateSpec.scala diff --git a/core/src/test/scala/core/TestHelper.scala b/core/test/core/TestHelper.scala similarity index 98% rename from core/src/test/scala/core/TestHelper.scala rename to core/test/core/TestHelper.scala index 24c53cca1..7ccdaad54 100644 --- a/core/src/test/scala/core/TestHelper.scala +++ b/core/test/core/TestHelper.scala @@ -118,11 +118,11 @@ object TestHelper extends ValidatedHelpers with ValidatedTestHelpers { Files.write(outputPath, bytes) } - def readFile(path: String): String = FileUtils.readToString(new File(path)) + def readFile(path: String): String = FileUtils.readToString(new File("../" + path)) def parseFile(filename: String): ValidatedNec[String, Service] = { val fetcher = MockServiceFetcher() - if (filename == "spec/apibuilder-api.json") { + if (filename.indexOf("spec/apibuilder-api.json")>=0) { Seq(io.apibuilder.spec.v0.Constants.Version, "latest").foreach { version => fetcher.add(s"/apibuilder-spec/$version/service.json", specService) fetcher.add(s"http://app.apibuilder.io/apicollective/apibuilder-common/$version/service.json", commonService) diff --git a/core/src/test/scala/core/TypeValidatorSpec.scala b/core/test/core/TypeValidatorSpec.scala similarity index 100% rename from core/src/test/scala/core/TypeValidatorSpec.scala rename to core/test/core/TypeValidatorSpec.scala diff --git a/core/src/test/scala/core/UnionTypeDefaultSpec.scala b/core/test/core/UnionTypeDefaultSpec.scala similarity index 100% rename from core/src/test/scala/core/UnionTypeDefaultSpec.scala rename to core/test/core/UnionTypeDefaultSpec.scala diff --git a/core/src/test/scala/core/UnionTypeDiscriminatorValueSpec.scala b/core/test/core/UnionTypeDiscriminatorValueSpec.scala similarity index 100% rename from core/src/test/scala/core/UnionTypeDiscriminatorValueSpec.scala rename to core/test/core/UnionTypeDiscriminatorValueSpec.scala diff --git a/core/src/test/scala/core/UnionTypeSpec.scala b/core/test/core/UnionTypeSpec.scala similarity index 99% rename from core/src/test/scala/core/UnionTypeSpec.scala rename to core/test/core/UnionTypeSpec.scala index a6d00aa1a..2051c909d 100644 --- a/core/src/test/scala/core/UnionTypeSpec.scala +++ b/core/test/core/UnionTypeSpec.scala @@ -7,7 +7,7 @@ import org.scalatest.matchers.should.Matchers class UnionTypeSpec extends AnyFunSpec with Matchers with ApiJsonHelpers { - private val baseJson = """ + private val baseJson = """ { "name": "Union Types Test", diff --git a/core/src/test/scala/core/UtilSpec.scala b/core/test/core/UtilSpec.scala similarity index 100% rename from core/src/test/scala/core/UtilSpec.scala rename to core/test/core/UtilSpec.scala diff --git a/core/src/test/scala/core/builder/JsonUtilSpec.scala b/core/test/core/builder/JsonUtilSpec.scala similarity index 100% rename from core/src/test/scala/core/builder/JsonUtilSpec.scala rename to core/test/core/builder/JsonUtilSpec.scala diff --git a/core/src/test/scala/core/builder/api_json/InternalDatatypeSpec.scala b/core/test/core/builder/api_json/InternalDatatypeSpec.scala similarity index 100% rename from core/src/test/scala/core/builder/api_json/InternalDatatypeSpec.scala rename to core/test/core/builder/api_json/InternalDatatypeSpec.scala diff --git a/core/src/test/scala/core/builder/api_json/templates/ModelMergeSpec.scala b/core/test/core/builder/api_json/templates/ModelMergeSpec.scala similarity index 99% rename from core/src/test/scala/core/builder/api_json/templates/ModelMergeSpec.scala rename to core/test/core/builder/api_json/templates/ModelMergeSpec.scala index 1cbb42b22..25f30e136 100644 --- a/core/src/test/scala/core/builder/api_json/templates/ModelMergeSpec.scala +++ b/core/test/core/builder/api_json/templates/ModelMergeSpec.scala @@ -158,7 +158,7 @@ class ModelMergeSpec extends AnyWordSpec with Matchers with ApiJsonHelpers { val field = makeField(default = None) setupFields( templateField = field.copy(default = Some(JsString("foo"))), - modelField = field.copy(default = modelFieldDefault.map(JsString)), + modelField = field.copy(default = modelFieldDefault.map(JsString(_))), ).head.default.get } diff --git a/core/src/test/scala/core/builder/api_json/templates/ResourceMergeSpec.scala b/core/test/core/builder/api_json/templates/ResourceMergeSpec.scala similarity index 100% rename from core/src/test/scala/core/builder/api_json/templates/ResourceMergeSpec.scala rename to core/test/core/builder/api_json/templates/ResourceMergeSpec.scala diff --git a/core/src/test/scala/core/builder/api_json/upgrades/RemoveApiDocElementSpec.scala b/core/test/core/builder/api_json/upgrades/RemoveApiDocElementSpec.scala similarity index 100% rename from core/src/test/scala/core/builder/api_json/upgrades/RemoveApiDocElementSpec.scala rename to core/test/core/builder/api_json/upgrades/RemoveApiDocElementSpec.scala diff --git a/core/src/test/scala/core/builder/api_json/upgrades/ServiceParserSpec.scala b/core/test/core/builder/api_json/upgrades/ServiceParserSpec.scala similarity index 100% rename from core/src/test/scala/core/builder/api_json/upgrades/ServiceParserSpec.scala rename to core/test/core/builder/api_json/upgrades/ServiceParserSpec.scala diff --git a/core/src/test/scala/helpers/ApiJsonHelpers.scala b/core/test/helpers/ApiJsonHelpers.scala similarity index 100% rename from core/src/test/scala/helpers/ApiJsonHelpers.scala rename to core/test/helpers/ApiJsonHelpers.scala diff --git a/core/src/test/scala/helpers/RandomHelpers.scala b/core/test/helpers/RandomHelpers.scala similarity index 100% rename from core/src/test/scala/helpers/RandomHelpers.scala rename to core/test/helpers/RandomHelpers.scala diff --git a/core/src/test/scala/helpers/ServiceHelpers.scala b/core/test/helpers/ServiceHelpers.scala similarity index 100% rename from core/src/test/scala/helpers/ServiceHelpers.scala rename to core/test/helpers/ServiceHelpers.scala diff --git a/core/src/test/scala/helpers/ValidatedTestHelpers.scala b/core/test/helpers/ValidatedTestHelpers.scala similarity index 78% rename from core/src/test/scala/helpers/ValidatedTestHelpers.scala rename to core/test/helpers/ValidatedTestHelpers.scala index ad202742d..db6a2069e 100644 --- a/core/src/test/scala/helpers/ValidatedTestHelpers.scala +++ b/core/test/helpers/ValidatedTestHelpers.scala @@ -5,14 +5,14 @@ import cats.data.ValidatedNec trait ValidatedTestHelpers { - def expectValid[T](r: ValidatedNec[_, T]): T = { + def expectValid[T, U](r: ValidatedNec[T, U]): U = { r match { case Valid(o) => o case Invalid(errors) => sys.error(s"Expected valid but was invalid: ${errors.toNonEmptyList}") } } - def expectInvalid[T](r: ValidatedNec[T, _]): Seq[T] = { + def expectInvalid[T, U](r: ValidatedNec[T, U]): Seq[T] = { r match { case Valid(_) => sys.error("Expected invalid but was valid") case Invalid(errors) => errors.toNonEmptyList.toList diff --git a/core/src/test/resources/apibuilder-service.json b/core/test/resources/apibuilder-service.json similarity index 100% rename from core/src/test/resources/apibuilder-service.json rename to core/test/resources/apibuilder-service.json diff --git a/core/src/test/resources/apidoc/plugin.properties b/core/test/resources/apidoc/plugin.properties similarity index 100% rename from core/src/test/resources/apidoc/plugin.properties rename to core/test/resources/apidoc/plugin.properties diff --git a/core/src/test/resources/avro/circular.avsc b/core/test/resources/avro/circular.avsc similarity index 100% rename from core/src/test/resources/avro/circular.avsc rename to core/test/resources/avro/circular.avsc diff --git a/core/src/test/resources/avro/circular.json b/core/test/resources/avro/circular.json similarity index 100% rename from core/src/test/resources/avro/circular.json rename to core/test/resources/avro/circular.json diff --git a/core/src/test/resources/avro/example.avsc b/core/test/resources/avro/example.avsc similarity index 100% rename from core/src/test/resources/avro/example.avsc rename to core/test/resources/avro/example.avsc diff --git a/core/src/test/resources/avro/example.json b/core/test/resources/avro/example.json similarity index 100% rename from core/src/test/resources/avro/example.json rename to core/test/resources/avro/example.json diff --git a/core/src/test/resources/generators/play-2-json-spec-readers-quality-plan-writers.txt b/core/test/resources/generators/play-2-json-spec-readers-quality-plan-writers.txt similarity index 100% rename from core/src/test/resources/generators/play-2-json-spec-readers-quality-plan-writers.txt rename to core/test/resources/generators/play-2-json-spec-readers-quality-plan-writers.txt diff --git a/core/src/test/resources/simple-w-array.json b/core/test/resources/simple-w-array.json similarity index 100% rename from core/src/test/resources/simple-w-array.json rename to core/test/resources/simple-w-array.json diff --git a/core/src/test/resources/simple-without-array.json b/core/test/resources/simple-without-array.json similarity index 100% rename from core/src/test/resources/simple-without-array.json rename to core/test/resources/simple-without-array.json diff --git a/core/src/test/resources/svc-iris-hub-0-0-1.json b/core/test/resources/svc-iris-hub-0-0-1.json similarity index 100% rename from core/src/test/resources/svc-iris-hub-0-0-1.json rename to core/test/resources/svc-iris-hub-0-0-1.json diff --git a/dao/spec/psql-apibuilder.json b/dao/spec/psql-apibuilder.json index 225c61fbf..52708ca52 100644 --- a/dao/spec/psql-apibuilder.json +++ b/dao/spec/psql-apibuilder.json @@ -1,5 +1,8 @@ { "name": "psql-apibuilder", + "attributes": [ + { "name": "scala", "value": { "version": "3.4" } } + ], "models": { "generator_invocation": { @@ -30,6 +33,7 @@ "package": "db.generated", "dao_user_class": "java.util.UUID", "id_generator": { + "class": "com.mbryzek.util.IdGenerator", "prefix": "gni" } } diff --git a/generated/app/ApicollectiveApibuilderApiV0Client.scala b/generated/app/ApicollectiveApibuilderApiV0Client.scala index 49743a409..2d9a409c2 100644 --- a/generated/app/ApicollectiveApibuilderApiV0Client.scala +++ b/generated/app/ApicollectiveApibuilderApiV0Client.scala @@ -1,7 +1,7 @@ /** * Generated by API Builder - https://www.apibuilder.io * Service version: 0.16.50 - * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-api/latest/play_2_8_client + * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-api/latest/play_2_9_scala_3_client */ package io.apibuilder.api.v0.models { @@ -1223,7 +1223,7 @@ package io.apibuilder.api.v0.models { } } - implicit def jsonReadsApibuilderApiApplicationSummary: play.api.libs.json.Reads[io.apibuilder.api.v0.models.ApplicationSummary] = { + def jsonReadsApibuilderApiApplicationSummary: play.api.libs.json.Reads[io.apibuilder.api.v0.models.ApplicationSummary] = { for { guid <- (__ \ "guid").read[_root_.java.util.UUID] organization <- (__ \ "organization").read[io.apibuilder.common.v0.models.Reference] @@ -1239,7 +1239,7 @@ package io.apibuilder.api.v0.models { ) ++ play.api.libs.json.Json.obj("type" -> "application_summary") } - implicit def jsonWritesApibuilderApiApplicationSummary: play.api.libs.json.Writes[ApplicationSummary] = { + def jsonWritesApibuilderApiApplicationSummary: play.api.libs.json.Writes[ApplicationSummary] = { (obj: io.apibuilder.api.v0.models.ApplicationSummary) => { io.apibuilder.api.v0.models.json.jsObjectApplicationSummary(obj) } @@ -1533,7 +1533,7 @@ package io.apibuilder.api.v0.models { } } - implicit def jsonReadsApibuilderApiDiffBreaking: play.api.libs.json.Reads[io.apibuilder.api.v0.models.DiffBreaking] = { + def jsonReadsApibuilderApiDiffBreaking: play.api.libs.json.Reads[io.apibuilder.api.v0.models.DiffBreaking] = { for { description <- (__ \ "description").read[String] isMaterial <- (__ \ "is_material").read[Boolean] @@ -1547,13 +1547,13 @@ package io.apibuilder.api.v0.models { ) ++ play.api.libs.json.Json.obj("type" -> "diff_breaking") } - implicit def jsonWritesApibuilderApiDiffBreaking: play.api.libs.json.Writes[DiffBreaking] = { + def jsonWritesApibuilderApiDiffBreaking: play.api.libs.json.Writes[DiffBreaking] = { (obj: io.apibuilder.api.v0.models.DiffBreaking) => { io.apibuilder.api.v0.models.json.jsObjectDiffBreaking(obj) } } - implicit def jsonReadsApibuilderApiDiffNonBreaking: play.api.libs.json.Reads[io.apibuilder.api.v0.models.DiffNonBreaking] = { + def jsonReadsApibuilderApiDiffNonBreaking: play.api.libs.json.Reads[io.apibuilder.api.v0.models.DiffNonBreaking] = { for { description <- (__ \ "description").read[String] isMaterial <- (__ \ "is_material").read[Boolean] @@ -1567,7 +1567,7 @@ package io.apibuilder.api.v0.models { ) ++ play.api.libs.json.Json.obj("type" -> "diff_non_breaking") } - implicit def jsonWritesApibuilderApiDiffNonBreaking: play.api.libs.json.Writes[DiffNonBreaking] = { + def jsonWritesApibuilderApiDiffNonBreaking: play.api.libs.json.Writes[DiffNonBreaking] = { (obj: io.apibuilder.api.v0.models.DiffNonBreaking) => { io.apibuilder.api.v0.models.json.jsObjectDiffNonBreaking(obj) } @@ -2277,7 +2277,7 @@ package io.apibuilder.api.v0.models { } } - implicit def jsonReadsApibuilderApiDiff: play.api.libs.json.Reads[io.apibuilder.api.v0.models.Diff] = (js: play.api.libs.json.JsValue) => { + implicit def jsonReadsApibuilderApiDiff[T <: io.apibuilder.api.v0.models.Diff]: play.api.libs.json.Reads[T] = (js: play.api.libs.json.JsValue) => { def readDiscriminator(discriminator: String) = { discriminator match { case "diff_breaking" => io.apibuilder.api.v0.models.json.jsonReadsApibuilderApiDiffBreaking.reads(js) @@ -2287,10 +2287,23 @@ package io.apibuilder.api.v0.models { } (js \ "type").validate[String] match { case e: play.api.libs.json.JsError => e - case s: play.api.libs.json.JsSuccess[String] => readDiscriminator(s.value) + case s: play.api.libs.json.JsSuccess[String] => readDiscriminator(s.value).map(_.asInstanceOf[T]) } } + + implicit def jsonReadsApibuilderApiDiffSeq[T <: io.apibuilder.api.v0.models.Diff]: play.api.libs.json.Reads[Seq[T]] = { + case a: play.api.libs.json.JsArray => { + val all: Seq[play.api.libs.json.JsResult[io.apibuilder.api.v0.models.Diff]] = a.value.map(jsonReadsApibuilderApiDiff.reads).toSeq + + all.collect { case e: play.api.libs.json.JsError => e }.toList match { + case Nil => play.api.libs.json.JsSuccess(all.collect { case play.api.libs.json.JsSuccess(v, _) => v.asInstanceOf[T] }) + case errors => play.api.libs.json.JsError(play.api.libs.json.JsError.merge(errors.flatMap(_.errors), Nil)) + } + } + case other => play.api.libs.json.JsError(s"Expected array but found [" + other.getClass.getName + "]") + } + def jsObjectDiff(obj: io.apibuilder.api.v0.models.Diff): play.api.libs.json.JsObject = { obj match { case x: io.apibuilder.api.v0.models.DiffBreaking => io.apibuilder.api.v0.models.json.jsObjectDiffBreaking(x) @@ -2300,13 +2313,15 @@ package io.apibuilder.api.v0.models { } } } - implicit def jsonWritesApibuilderApiDiff: play.api.libs.json.Writes[Diff] = { + + implicit def jsonWritesApibuilderApiDiff[T <: io.apibuilder.api.v0.models.Diff]: play.api.libs.json.Writes[T] = { (obj: io.apibuilder.api.v0.models.Diff) => { io.apibuilder.api.v0.models.json.jsObjectDiff(obj) } } - implicit def jsonReadsApibuilderApiItemDetail: play.api.libs.json.Reads[io.apibuilder.api.v0.models.ItemDetail] = (js: play.api.libs.json.JsValue) => { + + implicit def jsonReadsApibuilderApiItemDetail[T <: io.apibuilder.api.v0.models.ItemDetail]: play.api.libs.json.Reads[T] = (js: play.api.libs.json.JsValue) => { def readDiscriminator(discriminator: String) = { discriminator match { case "application_summary" => io.apibuilder.api.v0.models.json.jsonReadsApibuilderApiApplicationSummary.reads(js) @@ -2315,10 +2330,23 @@ package io.apibuilder.api.v0.models { } (js \ "type").validate[String] match { case e: play.api.libs.json.JsError => e - case s: play.api.libs.json.JsSuccess[String] => readDiscriminator(s.value) + case s: play.api.libs.json.JsSuccess[String] => readDiscriminator(s.value).map(_.asInstanceOf[T]) } } + + implicit def jsonReadsApibuilderApiItemDetailSeq[T <: io.apibuilder.api.v0.models.ItemDetail]: play.api.libs.json.Reads[Seq[T]] = { + case a: play.api.libs.json.JsArray => { + val all: Seq[play.api.libs.json.JsResult[io.apibuilder.api.v0.models.ItemDetail]] = a.value.map(jsonReadsApibuilderApiItemDetail.reads).toSeq + + all.collect { case e: play.api.libs.json.JsError => e }.toList match { + case Nil => play.api.libs.json.JsSuccess(all.collect { case play.api.libs.json.JsSuccess(v, _) => v.asInstanceOf[T] }) + case errors => play.api.libs.json.JsError(play.api.libs.json.JsError.merge(errors.flatMap(_.errors), Nil)) + } + } + case other => play.api.libs.json.JsError(s"Expected array but found [" + other.getClass.getName + "]") + } + def jsObjectItemDetail(obj: io.apibuilder.api.v0.models.ItemDetail): play.api.libs.json.JsObject = { obj match { case x: io.apibuilder.api.v0.models.ApplicationSummary => io.apibuilder.api.v0.models.json.jsObjectApplicationSummary(x) @@ -2327,7 +2355,8 @@ package io.apibuilder.api.v0.models { } } } - implicit def jsonWritesApibuilderApiItemDetail: play.api.libs.json.Writes[ItemDetail] = { + + implicit def jsonWritesApibuilderApiItemDetail[T <: io.apibuilder.api.v0.models.ItemDetail]: play.api.libs.json.Writes[T] = { (obj: io.apibuilder.api.v0.models.ItemDetail) => { io.apibuilder.api.v0.models.json.jsObjectItemDetail(obj) } @@ -2490,7 +2519,7 @@ package io.apibuilder.api.v0 { val BaseUrl = "https://api.apibuilder.io" val Namespace = "io.apibuilder.api.v0" - val UserAgent = "apibuilder app.apibuilder.io/apicollective/apibuilder-api/latest/play_2_8_client" + val UserAgent = "apibuilder app.apibuilder.io/apicollective/apibuilder-api/latest/play_2_9_scala_3_client" val Version = "0.16.50" val VersionMajor = 0 @@ -3723,7 +3752,7 @@ package io.apibuilder.api.v0 { "User-Agent" -> Constants.UserAgent, "X-Apidoc-Version" -> Constants.Version, "X-Apidoc-Version-Major" -> Constants.VersionMajor.toString - ).addHttpHeaders(defaultHeaders: _*) + ).addHttpHeaders(defaultHeaders*) auth.fold(holder) { case Authorization.Basic(username, password) => { holder.withAuth(username, password.getOrElse(""), play.api.libs.ws.WSAuthScheme.BASIC) @@ -3750,30 +3779,32 @@ package io.apibuilder.api.v0 { requestHeaders: Seq[(String, String)] = Nil, body: Option[play.api.libs.json.JsValue] = None ): scala.concurrent.Future[play.api.libs.ws.WSResponse] = { + import play.api.libs.ws.WSBodyWritables.writeableOf_JsValue + method.toUpperCase match { case "GET" => { - _logRequest("GET", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).get() + _logRequest("GET", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).get() } case "POST" => { - _logRequest("POST", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders): _*).addQueryStringParameters(queryParameters: _*)).post(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("POST", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders)*).addQueryStringParameters(queryParameters*)).post(body.getOrElse(play.api.libs.json.Json.obj())) } case "PUT" => { - _logRequest("PUT", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders): _*).addQueryStringParameters(queryParameters: _*)).put(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("PUT", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders)*).addQueryStringParameters(queryParameters*)).put(body.getOrElse(play.api.libs.json.Json.obj())) } case "PATCH" => { - _logRequest("PATCH", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).patch(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("PATCH", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).patch(body.getOrElse(play.api.libs.json.Json.obj())) } case "DELETE" => { - _logRequest("DELETE", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).delete() + _logRequest("DELETE", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).delete() } case "HEAD" => { - _logRequest("HEAD", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).head() + _logRequest("HEAD", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).head() } case "OPTIONS" => { - _logRequest("OPTIONS", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).options() + _logRequest("OPTIONS", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).options() } case _ => { - _logRequest(method, _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)) + _logRequest(method, _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)) sys.error("Unsupported method[%s]".format(method)) } } diff --git a/generated/app/ApicollectiveApibuilderCommonV0Client.scala b/generated/app/ApicollectiveApibuilderCommonV0Client.scala index 5ef7c293d..db48d10f9 100644 --- a/generated/app/ApicollectiveApibuilderCommonV0Client.scala +++ b/generated/app/ApicollectiveApibuilderCommonV0Client.scala @@ -1,7 +1,7 @@ /** * Generated by API Builder - https://www.apibuilder.io - * Service version: 0.16.48 - * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-common/latest/play_2_8_client + * Service version: 0.16.50 + * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-common/latest/play_2_9_scala_3_client */ package io.apibuilder.common.v0.models { @@ -322,8 +322,8 @@ package io.apibuilder.common.v0 { object Constants { val Namespace = "io.apibuilder.common.v0" - val UserAgent = "apibuilder app.apibuilder.io/apicollective/apibuilder-common/latest/play_2_8_client" - val Version = "0.16.48" + val UserAgent = "apibuilder app.apibuilder.io/apicollective/apibuilder-common/latest/play_2_9_scala_3_client" + val Version = "0.16.50" val VersionMajor = 0 } @@ -350,7 +350,7 @@ package io.apibuilder.common.v0 { "User-Agent" -> Constants.UserAgent, "X-Apidoc-Version" -> Constants.Version, "X-Apidoc-Version-Major" -> Constants.VersionMajor.toString - ).addHttpHeaders(defaultHeaders: _*) + ).addHttpHeaders(defaultHeaders*) auth.fold(holder) { case Authorization.Basic(username, password) => { holder.withAuth(username, password.getOrElse(""), play.api.libs.ws.WSAuthScheme.BASIC) @@ -377,30 +377,32 @@ package io.apibuilder.common.v0 { requestHeaders: Seq[(String, String)] = Nil, body: Option[play.api.libs.json.JsValue] = None ): scala.concurrent.Future[play.api.libs.ws.WSResponse] = { + import play.api.libs.ws.WSBodyWritables.writeableOf_JsValue + method.toUpperCase match { case "GET" => { - _logRequest("GET", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).get() + _logRequest("GET", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).get() } case "POST" => { - _logRequest("POST", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders): _*).addQueryStringParameters(queryParameters: _*)).post(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("POST", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders)*).addQueryStringParameters(queryParameters*)).post(body.getOrElse(play.api.libs.json.Json.obj())) } case "PUT" => { - _logRequest("PUT", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders): _*).addQueryStringParameters(queryParameters: _*)).put(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("PUT", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders)*).addQueryStringParameters(queryParameters*)).put(body.getOrElse(play.api.libs.json.Json.obj())) } case "PATCH" => { - _logRequest("PATCH", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).patch(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("PATCH", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).patch(body.getOrElse(play.api.libs.json.Json.obj())) } case "DELETE" => { - _logRequest("DELETE", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).delete() + _logRequest("DELETE", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).delete() } case "HEAD" => { - _logRequest("HEAD", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).head() + _logRequest("HEAD", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).head() } case "OPTIONS" => { - _logRequest("OPTIONS", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).options() + _logRequest("OPTIONS", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).options() } case _ => { - _logRequest(method, _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)) + _logRequest(method, _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)) sys.error("Unsupported method[%s]".format(method)) } } diff --git a/generated/app/ApicollectiveApibuilderCommonV0MockClient.scala b/generated/app/ApicollectiveApibuilderCommonV0MockClient.scala index 537b52348..377774515 100644 --- a/generated/app/ApicollectiveApibuilderCommonV0MockClient.scala +++ b/generated/app/ApicollectiveApibuilderCommonV0MockClient.scala @@ -1,7 +1,7 @@ /** * Generated by API Builder - https://www.apibuilder.io - * Service version: 0.16.43 - * apibuilder app.apibuilder.io/apicollective/apibuilder-common/latest/play_2_8_mock_client + * Service version: 0.16.50 + * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-common/latest/play_2_8_mock_client */ package io.apibuilder.common.v0.mock { diff --git a/generated/app/ApicollectiveApibuilderGeneratorV0Client.scala b/generated/app/ApicollectiveApibuilderGeneratorV0Client.scala index e04357f58..4021d7e52 100644 --- a/generated/app/ApicollectiveApibuilderGeneratorV0Client.scala +++ b/generated/app/ApicollectiveApibuilderGeneratorV0Client.scala @@ -1,7 +1,7 @@ /** * Generated by API Builder - https://www.apibuilder.io - * Service version: 0.16.48 - * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-generator/latest/play_2_8_client + * Service version: 0.16.50 + * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-generator/latest/play_2_9_scala_3_client */ package io.apibuilder.generator.v0.models { @@ -483,8 +483,8 @@ package io.apibuilder.generator.v0 { val BaseUrl = "https://api.apibuilder.io" val Namespace = "io.apibuilder.generator.v0" - val UserAgent = "apibuilder app.apibuilder.io/apicollective/apibuilder-generator/latest/play_2_8_client" - val Version = "0.16.48" + val UserAgent = "apibuilder app.apibuilder.io/apicollective/apibuilder-generator/latest/play_2_9_scala_3_client" + val Version = "0.16.50" val VersionMajor = 0 } @@ -573,7 +573,7 @@ package io.apibuilder.generator.v0 { "User-Agent" -> Constants.UserAgent, "X-Apidoc-Version" -> Constants.Version, "X-Apidoc-Version-Major" -> Constants.VersionMajor.toString - ).addHttpHeaders(defaultHeaders: _*) + ).addHttpHeaders(defaultHeaders*) auth.fold(holder) { case Authorization.Basic(username, password) => { holder.withAuth(username, password.getOrElse(""), play.api.libs.ws.WSAuthScheme.BASIC) @@ -600,30 +600,32 @@ package io.apibuilder.generator.v0 { requestHeaders: Seq[(String, String)] = Nil, body: Option[play.api.libs.json.JsValue] = None ): scala.concurrent.Future[play.api.libs.ws.WSResponse] = { + import play.api.libs.ws.WSBodyWritables.writeableOf_JsValue + method.toUpperCase match { case "GET" => { - _logRequest("GET", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).get() + _logRequest("GET", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).get() } case "POST" => { - _logRequest("POST", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders): _*).addQueryStringParameters(queryParameters: _*)).post(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("POST", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders)*).addQueryStringParameters(queryParameters*)).post(body.getOrElse(play.api.libs.json.Json.obj())) } case "PUT" => { - _logRequest("PUT", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders): _*).addQueryStringParameters(queryParameters: _*)).put(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("PUT", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders)*).addQueryStringParameters(queryParameters*)).put(body.getOrElse(play.api.libs.json.Json.obj())) } case "PATCH" => { - _logRequest("PATCH", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).patch(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("PATCH", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).patch(body.getOrElse(play.api.libs.json.Json.obj())) } case "DELETE" => { - _logRequest("DELETE", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).delete() + _logRequest("DELETE", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).delete() } case "HEAD" => { - _logRequest("HEAD", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).head() + _logRequest("HEAD", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).head() } case "OPTIONS" => { - _logRequest("OPTIONS", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).options() + _logRequest("OPTIONS", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).options() } case _ => { - _logRequest(method, _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)) + _logRequest(method, _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)) sys.error("Unsupported method[%s]".format(method)) } } diff --git a/generated/app/ApicollectiveApibuilderGeneratorV0MockClient.scala b/generated/app/ApicollectiveApibuilderGeneratorV0MockClient.scala index 6d8a37e64..08841f71d 100644 --- a/generated/app/ApicollectiveApibuilderGeneratorV0MockClient.scala +++ b/generated/app/ApicollectiveApibuilderGeneratorV0MockClient.scala @@ -1,7 +1,7 @@ /** * Generated by API Builder - https://www.apibuilder.io - * Service version: 0.16.43 - * apibuilder app.apibuilder.io/apicollective/apibuilder-generator/latest/play_2_8_mock_client + * Service version: 0.16.50 + * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-generator/latest/play_2_8_mock_client */ package io.apibuilder.generator.v0.mock { diff --git a/generated/app/ApicollectiveApibuilderSpecV0Client.scala b/generated/app/ApicollectiveApibuilderSpecV0Client.scala index 4d4ad44b6..78fc3e50c 100644 --- a/generated/app/ApicollectiveApibuilderSpecV0Client.scala +++ b/generated/app/ApicollectiveApibuilderSpecV0Client.scala @@ -1,7 +1,7 @@ /** * Generated by API Builder - https://www.apibuilder.io - * Service version: 0.16.48 - * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-spec/latest/play_2_8_client + * Service version: 0.16.50 + * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-spec/latest/play_2_9_scala_3_client */ package io.apibuilder.spec.v0.models { @@ -1389,14 +1389,27 @@ package io.apibuilder.spec.v0.models { (__ \ "value").read[Int].map { x => ResponseCodeInt(value = x) } } - implicit def jsonReadsApibuilderSpecResponseCode: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.ResponseCode] = { - ( - (__ \ "integer").read(jsonReadsApibuilderSpecResponseCodeInt).asInstanceOf[play.api.libs.json.Reads[ResponseCode]] - orElse - (__ \ "response_code_option").read(jsonReadsApibuilderSpecResponseCodeOption).asInstanceOf[play.api.libs.json.Reads[ResponseCode]] - orElse - play.api.libs.json.Reads(jsValue => play.api.libs.json.JsSuccess(ResponseCodeUndefinedType(jsValue.toString))).asInstanceOf[play.api.libs.json.Reads[ResponseCode]] + implicit def jsonReadsApibuilderSpecResponseCode[T <: io.apibuilder.spec.v0.models.ResponseCode]: play.api.libs.json.Reads[T] = (json: play.api.libs.json.JsValue) => { + val default = jsonReadsApibuilderSpecResponseCodeInt.reads(json).map(_.asInstanceOf[T]) + val all: Seq[play.api.libs.json.JsResult[T]] = Seq( + default, + jsonReadsApibuilderSpecResponseCodeOption.reads(json).map(_.asInstanceOf[T]) ) + all.view.find(_.isSuccess).getOrElse(default) + } + + + + implicit def jsonReadsApibuilderSpecResponseCodeSeq[T <: io.apibuilder.spec.v0.models.ResponseCode]: play.api.libs.json.Reads[Seq[T]] = { + case a: play.api.libs.json.JsArray => { + val all: Seq[play.api.libs.json.JsResult[io.apibuilder.spec.v0.models.ResponseCode]] = a.value.map(jsonReadsApibuilderSpecResponseCode.reads).toSeq + + all.collect { case e: play.api.libs.json.JsError => e }.toList match { + case Nil => play.api.libs.json.JsSuccess(all.collect { case play.api.libs.json.JsSuccess(v, _) => v.asInstanceOf[T] }) + case errors => play.api.libs.json.JsError(play.api.libs.json.JsError.merge(errors.flatMap(_.errors), Nil)) + } + } + case other => play.api.libs.json.JsError(s"Expected array but found [" + other.getClass.getName + "]") } def jsObjectResponseCode(obj: io.apibuilder.spec.v0.models.ResponseCode): play.api.libs.json.JsObject = { @@ -1406,7 +1419,8 @@ package io.apibuilder.spec.v0.models { case x: io.apibuilder.spec.v0.models.ResponseCodeUndefinedType => sys.error(s"The type[io.apibuilder.spec.v0.models.ResponseCodeUndefinedType] should never be serialized") } } - implicit def jsonWritesApibuilderSpecResponseCode: play.api.libs.json.Writes[ResponseCode] = { + + implicit def jsonWritesApibuilderSpecResponseCode[T <: io.apibuilder.spec.v0.models.ResponseCode]: play.api.libs.json.Writes[T] = { (obj: io.apibuilder.spec.v0.models.ResponseCode) => { io.apibuilder.spec.v0.models.json.jsObjectResponseCode(obj) } @@ -1550,8 +1564,8 @@ package io.apibuilder.spec.v0 { object Constants { val Namespace = "io.apibuilder.spec.v0" - val UserAgent = "apibuilder app.apibuilder.io/apicollective/apibuilder-spec/latest/play_2_8_client" - val Version = "0.16.48" + val UserAgent = "apibuilder app.apibuilder.io/apicollective/apibuilder-spec/latest/play_2_9_scala_3_client" + val Version = "0.16.50" val VersionMajor = 0 } @@ -1578,7 +1592,7 @@ package io.apibuilder.spec.v0 { "User-Agent" -> Constants.UserAgent, "X-Apidoc-Version" -> Constants.Version, "X-Apidoc-Version-Major" -> Constants.VersionMajor.toString - ).addHttpHeaders(defaultHeaders: _*) + ).addHttpHeaders(defaultHeaders*) auth.fold(holder) { case Authorization.Basic(username, password) => { holder.withAuth(username, password.getOrElse(""), play.api.libs.ws.WSAuthScheme.BASIC) @@ -1605,30 +1619,32 @@ package io.apibuilder.spec.v0 { requestHeaders: Seq[(String, String)] = Nil, body: Option[play.api.libs.json.JsValue] = None ): scala.concurrent.Future[play.api.libs.ws.WSResponse] = { + import play.api.libs.ws.WSBodyWritables.writeableOf_JsValue + method.toUpperCase match { case "GET" => { - _logRequest("GET", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).get() + _logRequest("GET", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).get() } case "POST" => { - _logRequest("POST", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders): _*).addQueryStringParameters(queryParameters: _*)).post(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("POST", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders)*).addQueryStringParameters(queryParameters*)).post(body.getOrElse(play.api.libs.json.Json.obj())) } case "PUT" => { - _logRequest("PUT", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders): _*).addQueryStringParameters(queryParameters: _*)).put(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("PUT", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders)*).addQueryStringParameters(queryParameters*)).put(body.getOrElse(play.api.libs.json.Json.obj())) } case "PATCH" => { - _logRequest("PATCH", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).patch(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("PATCH", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).patch(body.getOrElse(play.api.libs.json.Json.obj())) } case "DELETE" => { - _logRequest("DELETE", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).delete() + _logRequest("DELETE", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).delete() } case "HEAD" => { - _logRequest("HEAD", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).head() + _logRequest("HEAD", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).head() } case "OPTIONS" => { - _logRequest("OPTIONS", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).options() + _logRequest("OPTIONS", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).options() } case _ => { - _logRequest(method, _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)) + _logRequest(method, _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)) sys.error("Unsupported method[%s]".format(method)) } } diff --git a/generated/app/ApicollectiveApibuilderSpecV0MockClient.scala b/generated/app/ApicollectiveApibuilderSpecV0MockClient.scala index 489ef22c4..464e0983e 100644 --- a/generated/app/ApicollectiveApibuilderSpecV0MockClient.scala +++ b/generated/app/ApicollectiveApibuilderSpecV0MockClient.scala @@ -1,7 +1,7 @@ /** * Generated by API Builder - https://www.apibuilder.io - * Service version: 0.16.43 - * apibuilder app.apibuilder.io/apicollective/apibuilder-spec/latest/play_2_8_mock_client + * Service version: 0.16.50 + * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-spec/latest/play_2_8_mock_client */ package io.apibuilder.spec.v0.mock { diff --git a/generated/app/ApicollectiveApibuilderTaskV0Client.scala b/generated/app/ApicollectiveApibuilderTaskV0Client.scala index 54db61ad4..e16223600 100644 --- a/generated/app/ApicollectiveApibuilderTaskV0Client.scala +++ b/generated/app/ApicollectiveApibuilderTaskV0Client.scala @@ -1,11 +1,41 @@ /** * Generated by API Builder - https://www.apibuilder.io * Service version: 0.16.50 - * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-task/latest/play_2_8_client + * User agent: apibuilder localhost 9000/apicollective/apibuilder-task/latest/play_2_9_scala_3_client */ package io.apibuilder.task.v0.models { - sealed trait EmailData extends _root_.scala.Product with _root_.scala.Serializable + sealed trait EmailData extends _root_.scala.Product with _root_.scala.Serializable { + def emailDataDiscriminator: EmailDataDiscriminator + + } + + /** + * Defines the valid discriminator values for the type EmailData + */ + sealed trait EmailDataDiscriminator extends _root_.scala.Product with _root_.scala.Serializable + + object EmailDataDiscriminator { + + case object EmailDataApplicationCreated extends EmailDataDiscriminator { override def toString = "email_data_application_created" } + case object EmailDataEmailVerificationCreated extends EmailDataDiscriminator { override def toString = "email_data_email_verification_created" } + case object EmailDataMembershipCreated extends EmailDataDiscriminator { override def toString = "email_data_membership_created" } + case object EmailDataMembershipRequestCreated extends EmailDataDiscriminator { override def toString = "email_data_membership_request_created" } + case object EmailDataMembershipRequestAccepted extends EmailDataDiscriminator { override def toString = "email_data_membership_request_accepted" } + case object EmailDataMembershipRequestDeclined extends EmailDataDiscriminator { override def toString = "email_data_membership_request_declined" } + case object EmailDataPasswordResetRequestCreated extends EmailDataDiscriminator { override def toString = "email_data_password_reset_request_created" } + + final case class UNDEFINED(override val toString: String) extends EmailDataDiscriminator + + val all: scala.List[EmailDataDiscriminator] = scala.List(EmailDataApplicationCreated, EmailDataEmailVerificationCreated, EmailDataMembershipCreated, EmailDataMembershipRequestCreated, EmailDataMembershipRequestAccepted, EmailDataMembershipRequestDeclined, EmailDataPasswordResetRequestCreated) + + private val byName: Map[String, EmailDataDiscriminator] = all.map(x => x.toString.toLowerCase -> x).toMap + + def apply(value: String): EmailDataDiscriminator = fromString(value).getOrElse(UNDEFINED(value)) + + def fromString(value: String): _root_.scala.Option[EmailDataDiscriminator] = byName.get(value.toLowerCase) + + } final case class DiffVersionData( oldVersionGuid: _root_.java.util.UUID, newVersionGuid: _root_.java.util.UUID @@ -13,34 +43,48 @@ package io.apibuilder.task.v0.models { final case class EmailDataApplicationCreated( applicationGuid: _root_.java.util.UUID - ) extends EmailData + ) extends EmailData { + override val emailDataDiscriminator: EmailDataDiscriminator = EmailDataDiscriminator.EmailDataApplicationCreated + } final case class EmailDataEmailVerificationCreated( guid: _root_.java.util.UUID - ) extends EmailData + ) extends EmailData { + override val emailDataDiscriminator: EmailDataDiscriminator = EmailDataDiscriminator.EmailDataEmailVerificationCreated + } final case class EmailDataMembershipCreated( guid: _root_.java.util.UUID - ) extends EmailData + ) extends EmailData { + override val emailDataDiscriminator: EmailDataDiscriminator = EmailDataDiscriminator.EmailDataMembershipCreated + } final case class EmailDataMembershipRequestAccepted( organizationGuid: _root_.java.util.UUID, userGuid: _root_.java.util.UUID, role: io.apibuilder.common.v0.models.MembershipRole - ) extends EmailData + ) extends EmailData { + override val emailDataDiscriminator: EmailDataDiscriminator = EmailDataDiscriminator.EmailDataMembershipRequestAccepted + } final case class EmailDataMembershipRequestCreated( guid: _root_.java.util.UUID - ) extends EmailData + ) extends EmailData { + override val emailDataDiscriminator: EmailDataDiscriminator = EmailDataDiscriminator.EmailDataMembershipRequestCreated + } final case class EmailDataMembershipRequestDeclined( organizationGuid: _root_.java.util.UUID, userGuid: _root_.java.util.UUID - ) extends EmailData + ) extends EmailData { + override val emailDataDiscriminator: EmailDataDiscriminator = EmailDataDiscriminator.EmailDataMembershipRequestDeclined + } final case class EmailDataPasswordResetRequestCreated( guid: _root_.java.util.UUID - ) extends EmailData + ) extends EmailData { + override val emailDataDiscriminator: EmailDataDiscriminator = EmailDataDiscriminator.EmailDataPasswordResetRequestCreated + } /** * Provides future compatibility in clients - in the future, when a type is added @@ -53,7 +97,9 @@ package io.apibuilder.task.v0.models { final case class EmailDataUndefinedType( description: String - ) extends EmailData + ) extends EmailData { + override val emailDataDiscriminator: EmailDataDiscriminator = EmailDataDiscriminator.UNDEFINED(description) + } sealed trait TaskType extends _root_.scala.Product with _root_.scala.Serializable object TaskType { @@ -183,55 +229,55 @@ package io.apibuilder.task.v0.models { } } - implicit def jsonReadsApibuilderTaskEmailDataApplicationCreated: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataApplicationCreated] = { + def jsonReadsApibuilderTaskEmailDataApplicationCreated: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataApplicationCreated] = { (__ \ "application_guid").read[_root_.java.util.UUID].map { x => EmailDataApplicationCreated(applicationGuid = x) } } def jsObjectEmailDataApplicationCreated(obj: io.apibuilder.task.v0.models.EmailDataApplicationCreated): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "application_guid" -> play.api.libs.json.JsString(obj.applicationGuid.toString) - ) + ) ++ play.api.libs.json.Json.obj("discriminator" -> "email_data_application_created") } - implicit def jsonWritesApibuilderTaskEmailDataApplicationCreated: play.api.libs.json.Writes[EmailDataApplicationCreated] = { + def jsonWritesApibuilderTaskEmailDataApplicationCreated: play.api.libs.json.Writes[EmailDataApplicationCreated] = { (obj: io.apibuilder.task.v0.models.EmailDataApplicationCreated) => { io.apibuilder.task.v0.models.json.jsObjectEmailDataApplicationCreated(obj) } } - implicit def jsonReadsApibuilderTaskEmailDataEmailVerificationCreated: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataEmailVerificationCreated] = { + def jsonReadsApibuilderTaskEmailDataEmailVerificationCreated: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataEmailVerificationCreated] = { (__ \ "guid").read[_root_.java.util.UUID].map { x => EmailDataEmailVerificationCreated(guid = x) } } def jsObjectEmailDataEmailVerificationCreated(obj: io.apibuilder.task.v0.models.EmailDataEmailVerificationCreated): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "guid" -> play.api.libs.json.JsString(obj.guid.toString) - ) + ) ++ play.api.libs.json.Json.obj("discriminator" -> "email_data_email_verification_created") } - implicit def jsonWritesApibuilderTaskEmailDataEmailVerificationCreated: play.api.libs.json.Writes[EmailDataEmailVerificationCreated] = { + def jsonWritesApibuilderTaskEmailDataEmailVerificationCreated: play.api.libs.json.Writes[EmailDataEmailVerificationCreated] = { (obj: io.apibuilder.task.v0.models.EmailDataEmailVerificationCreated) => { io.apibuilder.task.v0.models.json.jsObjectEmailDataEmailVerificationCreated(obj) } } - implicit def jsonReadsApibuilderTaskEmailDataMembershipCreated: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataMembershipCreated] = { + def jsonReadsApibuilderTaskEmailDataMembershipCreated: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataMembershipCreated] = { (__ \ "guid").read[_root_.java.util.UUID].map { x => EmailDataMembershipCreated(guid = x) } } def jsObjectEmailDataMembershipCreated(obj: io.apibuilder.task.v0.models.EmailDataMembershipCreated): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "guid" -> play.api.libs.json.JsString(obj.guid.toString) - ) + ) ++ play.api.libs.json.Json.obj("discriminator" -> "email_data_membership_created") } - implicit def jsonWritesApibuilderTaskEmailDataMembershipCreated: play.api.libs.json.Writes[EmailDataMembershipCreated] = { + def jsonWritesApibuilderTaskEmailDataMembershipCreated: play.api.libs.json.Writes[EmailDataMembershipCreated] = { (obj: io.apibuilder.task.v0.models.EmailDataMembershipCreated) => { io.apibuilder.task.v0.models.json.jsObjectEmailDataMembershipCreated(obj) } } - implicit def jsonReadsApibuilderTaskEmailDataMembershipRequestAccepted: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataMembershipRequestAccepted] = { + def jsonReadsApibuilderTaskEmailDataMembershipRequestAccepted: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataMembershipRequestAccepted] = { for { organizationGuid <- (__ \ "organization_guid").read[_root_.java.util.UUID] userGuid <- (__ \ "user_guid").read[_root_.java.util.UUID] @@ -244,32 +290,32 @@ package io.apibuilder.task.v0.models { "organization_guid" -> play.api.libs.json.JsString(obj.organizationGuid.toString), "user_guid" -> play.api.libs.json.JsString(obj.userGuid.toString), "role" -> play.api.libs.json.JsString(obj.role.toString) - ) + ) ++ play.api.libs.json.Json.obj("discriminator" -> "email_data_membership_request_accepted") } - implicit def jsonWritesApibuilderTaskEmailDataMembershipRequestAccepted: play.api.libs.json.Writes[EmailDataMembershipRequestAccepted] = { + def jsonWritesApibuilderTaskEmailDataMembershipRequestAccepted: play.api.libs.json.Writes[EmailDataMembershipRequestAccepted] = { (obj: io.apibuilder.task.v0.models.EmailDataMembershipRequestAccepted) => { io.apibuilder.task.v0.models.json.jsObjectEmailDataMembershipRequestAccepted(obj) } } - implicit def jsonReadsApibuilderTaskEmailDataMembershipRequestCreated: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataMembershipRequestCreated] = { + def jsonReadsApibuilderTaskEmailDataMembershipRequestCreated: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataMembershipRequestCreated] = { (__ \ "guid").read[_root_.java.util.UUID].map { x => EmailDataMembershipRequestCreated(guid = x) } } def jsObjectEmailDataMembershipRequestCreated(obj: io.apibuilder.task.v0.models.EmailDataMembershipRequestCreated): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "guid" -> play.api.libs.json.JsString(obj.guid.toString) - ) + ) ++ play.api.libs.json.Json.obj("discriminator" -> "email_data_membership_request_created") } - implicit def jsonWritesApibuilderTaskEmailDataMembershipRequestCreated: play.api.libs.json.Writes[EmailDataMembershipRequestCreated] = { + def jsonWritesApibuilderTaskEmailDataMembershipRequestCreated: play.api.libs.json.Writes[EmailDataMembershipRequestCreated] = { (obj: io.apibuilder.task.v0.models.EmailDataMembershipRequestCreated) => { io.apibuilder.task.v0.models.json.jsObjectEmailDataMembershipRequestCreated(obj) } } - implicit def jsonReadsApibuilderTaskEmailDataMembershipRequestDeclined: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataMembershipRequestDeclined] = { + def jsonReadsApibuilderTaskEmailDataMembershipRequestDeclined: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataMembershipRequestDeclined] = { for { organizationGuid <- (__ \ "organization_guid").read[_root_.java.util.UUID] userGuid <- (__ \ "user_guid").read[_root_.java.util.UUID] @@ -280,64 +326,79 @@ package io.apibuilder.task.v0.models { play.api.libs.json.Json.obj( "organization_guid" -> play.api.libs.json.JsString(obj.organizationGuid.toString), "user_guid" -> play.api.libs.json.JsString(obj.userGuid.toString) - ) + ) ++ play.api.libs.json.Json.obj("discriminator" -> "email_data_membership_request_declined") } - implicit def jsonWritesApibuilderTaskEmailDataMembershipRequestDeclined: play.api.libs.json.Writes[EmailDataMembershipRequestDeclined] = { + def jsonWritesApibuilderTaskEmailDataMembershipRequestDeclined: play.api.libs.json.Writes[EmailDataMembershipRequestDeclined] = { (obj: io.apibuilder.task.v0.models.EmailDataMembershipRequestDeclined) => { io.apibuilder.task.v0.models.json.jsObjectEmailDataMembershipRequestDeclined(obj) } } - implicit def jsonReadsApibuilderTaskEmailDataPasswordResetRequestCreated: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataPasswordResetRequestCreated] = { + def jsonReadsApibuilderTaskEmailDataPasswordResetRequestCreated: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailDataPasswordResetRequestCreated] = { (__ \ "guid").read[_root_.java.util.UUID].map { x => EmailDataPasswordResetRequestCreated(guid = x) } } def jsObjectEmailDataPasswordResetRequestCreated(obj: io.apibuilder.task.v0.models.EmailDataPasswordResetRequestCreated): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "guid" -> play.api.libs.json.JsString(obj.guid.toString) - ) + ) ++ play.api.libs.json.Json.obj("discriminator" -> "email_data_password_reset_request_created") } - implicit def jsonWritesApibuilderTaskEmailDataPasswordResetRequestCreated: play.api.libs.json.Writes[EmailDataPasswordResetRequestCreated] = { + def jsonWritesApibuilderTaskEmailDataPasswordResetRequestCreated: play.api.libs.json.Writes[EmailDataPasswordResetRequestCreated] = { (obj: io.apibuilder.task.v0.models.EmailDataPasswordResetRequestCreated) => { io.apibuilder.task.v0.models.json.jsObjectEmailDataPasswordResetRequestCreated(obj) } } - implicit def jsonReadsApibuilderTaskEmailData: play.api.libs.json.Reads[io.apibuilder.task.v0.models.EmailData] = { - ( - (__ \ "email_data_application_created").read(jsonReadsApibuilderTaskEmailDataApplicationCreated).asInstanceOf[play.api.libs.json.Reads[EmailData]] - orElse - (__ \ "email_data_email_verification_created").read(jsonReadsApibuilderTaskEmailDataEmailVerificationCreated).asInstanceOf[play.api.libs.json.Reads[EmailData]] - orElse - (__ \ "email_data_membership_created").read(jsonReadsApibuilderTaskEmailDataMembershipCreated).asInstanceOf[play.api.libs.json.Reads[EmailData]] - orElse - (__ \ "email_data_membership_request_created").read(jsonReadsApibuilderTaskEmailDataMembershipRequestCreated).asInstanceOf[play.api.libs.json.Reads[EmailData]] - orElse - (__ \ "email_data_membership_request_accepted").read(jsonReadsApibuilderTaskEmailDataMembershipRequestAccepted).asInstanceOf[play.api.libs.json.Reads[EmailData]] - orElse - (__ \ "email_data_membership_request_declined").read(jsonReadsApibuilderTaskEmailDataMembershipRequestDeclined).asInstanceOf[play.api.libs.json.Reads[EmailData]] - orElse - (__ \ "email_data_password_reset_request_created").read(jsonReadsApibuilderTaskEmailDataPasswordResetRequestCreated).asInstanceOf[play.api.libs.json.Reads[EmailData]] - orElse - play.api.libs.json.Reads(jsValue => play.api.libs.json.JsSuccess(EmailDataUndefinedType(jsValue.toString))).asInstanceOf[play.api.libs.json.Reads[EmailData]] - ) + implicit def jsonReadsApibuilderTaskEmailData[T <: io.apibuilder.task.v0.models.EmailData]: play.api.libs.json.Reads[T] = (js: play.api.libs.json.JsValue) => { + def readDiscriminator(discriminator: String) = { + discriminator match { + case "email_data_application_created" => io.apibuilder.task.v0.models.json.jsonReadsApibuilderTaskEmailDataApplicationCreated.reads(js) + case "email_data_email_verification_created" => io.apibuilder.task.v0.models.json.jsonReadsApibuilderTaskEmailDataEmailVerificationCreated.reads(js) + case "email_data_membership_created" => io.apibuilder.task.v0.models.json.jsonReadsApibuilderTaskEmailDataMembershipCreated.reads(js) + case "email_data_membership_request_created" => io.apibuilder.task.v0.models.json.jsonReadsApibuilderTaskEmailDataMembershipRequestCreated.reads(js) + case "email_data_membership_request_accepted" => io.apibuilder.task.v0.models.json.jsonReadsApibuilderTaskEmailDataMembershipRequestAccepted.reads(js) + case "email_data_membership_request_declined" => io.apibuilder.task.v0.models.json.jsonReadsApibuilderTaskEmailDataMembershipRequestDeclined.reads(js) + case "email_data_password_reset_request_created" => io.apibuilder.task.v0.models.json.jsonReadsApibuilderTaskEmailDataPasswordResetRequestCreated.reads(js) + case other => play.api.libs.json.JsSuccess(io.apibuilder.task.v0.models.EmailDataUndefinedType(other)) + } + } + (js \ "discriminator").validate[String] match { + case e: play.api.libs.json.JsError => e + case s: play.api.libs.json.JsSuccess[String] => readDiscriminator(s.value).map(_.asInstanceOf[T]) + } + } + + + implicit def jsonReadsApibuilderTaskEmailDataSeq[T <: io.apibuilder.task.v0.models.EmailData]: play.api.libs.json.Reads[Seq[T]] = { + case a: play.api.libs.json.JsArray => { + val all: Seq[play.api.libs.json.JsResult[io.apibuilder.task.v0.models.EmailData]] = a.value.map(jsonReadsApibuilderTaskEmailData.reads).toSeq + + all.collect { case e: play.api.libs.json.JsError => e }.toList match { + case Nil => play.api.libs.json.JsSuccess(all.collect { case play.api.libs.json.JsSuccess(v, _) => v.asInstanceOf[T] }) + case errors => play.api.libs.json.JsError(play.api.libs.json.JsError.merge(errors.flatMap(_.errors), Nil)) + } + } + case other => play.api.libs.json.JsError(s"Expected array but found [" + other.getClass.getName + "]") } def jsObjectEmailData(obj: io.apibuilder.task.v0.models.EmailData): play.api.libs.json.JsObject = { obj match { - case x: io.apibuilder.task.v0.models.EmailDataApplicationCreated => play.api.libs.json.Json.obj("email_data_application_created" -> io.apibuilder.task.v0.models.json.jsObjectEmailDataApplicationCreated(x)) - case x: io.apibuilder.task.v0.models.EmailDataEmailVerificationCreated => play.api.libs.json.Json.obj("email_data_email_verification_created" -> io.apibuilder.task.v0.models.json.jsObjectEmailDataEmailVerificationCreated(x)) - case x: io.apibuilder.task.v0.models.EmailDataMembershipCreated => play.api.libs.json.Json.obj("email_data_membership_created" -> io.apibuilder.task.v0.models.json.jsObjectEmailDataMembershipCreated(x)) - case x: io.apibuilder.task.v0.models.EmailDataMembershipRequestCreated => play.api.libs.json.Json.obj("email_data_membership_request_created" -> io.apibuilder.task.v0.models.json.jsObjectEmailDataMembershipRequestCreated(x)) - case x: io.apibuilder.task.v0.models.EmailDataMembershipRequestAccepted => play.api.libs.json.Json.obj("email_data_membership_request_accepted" -> io.apibuilder.task.v0.models.json.jsObjectEmailDataMembershipRequestAccepted(x)) - case x: io.apibuilder.task.v0.models.EmailDataMembershipRequestDeclined => play.api.libs.json.Json.obj("email_data_membership_request_declined" -> io.apibuilder.task.v0.models.json.jsObjectEmailDataMembershipRequestDeclined(x)) - case x: io.apibuilder.task.v0.models.EmailDataPasswordResetRequestCreated => play.api.libs.json.Json.obj("email_data_password_reset_request_created" -> io.apibuilder.task.v0.models.json.jsObjectEmailDataPasswordResetRequestCreated(x)) - case x: io.apibuilder.task.v0.models.EmailDataUndefinedType => sys.error(s"The type[io.apibuilder.task.v0.models.EmailDataUndefinedType] should never be serialized") + case x: io.apibuilder.task.v0.models.EmailDataApplicationCreated => io.apibuilder.task.v0.models.json.jsObjectEmailDataApplicationCreated(x) + case x: io.apibuilder.task.v0.models.EmailDataEmailVerificationCreated => io.apibuilder.task.v0.models.json.jsObjectEmailDataEmailVerificationCreated(x) + case x: io.apibuilder.task.v0.models.EmailDataMembershipCreated => io.apibuilder.task.v0.models.json.jsObjectEmailDataMembershipCreated(x) + case x: io.apibuilder.task.v0.models.EmailDataMembershipRequestCreated => io.apibuilder.task.v0.models.json.jsObjectEmailDataMembershipRequestCreated(x) + case x: io.apibuilder.task.v0.models.EmailDataMembershipRequestAccepted => io.apibuilder.task.v0.models.json.jsObjectEmailDataMembershipRequestAccepted(x) + case x: io.apibuilder.task.v0.models.EmailDataMembershipRequestDeclined => io.apibuilder.task.v0.models.json.jsObjectEmailDataMembershipRequestDeclined(x) + case x: io.apibuilder.task.v0.models.EmailDataPasswordResetRequestCreated => io.apibuilder.task.v0.models.json.jsObjectEmailDataPasswordResetRequestCreated(x) + case other => { + sys.error(s"The type[${other.getClass.getName}] has no JSON writer") + } } } - implicit def jsonWritesApibuilderTaskEmailData: play.api.libs.json.Writes[EmailData] = { + + implicit def jsonWritesApibuilderTaskEmailData[T <: io.apibuilder.task.v0.models.EmailData]: play.api.libs.json.Writes[T] = { (obj: io.apibuilder.task.v0.models.EmailData) => { io.apibuilder.task.v0.models.json.jsObjectEmailData(obj) } @@ -463,7 +524,7 @@ package io.apibuilder.task.v0 { object Constants { val Namespace = "io.apibuilder.task.v0" - val UserAgent = "apibuilder app.apibuilder.io/apicollective/apibuilder-task/latest/play_2_8_client" + val UserAgent = "apibuilder localhost 9000/apicollective/apibuilder-task/latest/play_2_9_scala_3_client" val Version = "0.16.50" val VersionMajor = 0 @@ -492,7 +553,7 @@ package io.apibuilder.task.v0 { "User-Agent" -> Constants.UserAgent, "X-Apidoc-Version" -> Constants.Version, "X-Apidoc-Version-Major" -> Constants.VersionMajor.toString - ).addHttpHeaders(defaultHeaders: _*) + ).addHttpHeaders(defaultHeaders*) auth.fold(holder) { case Authorization.Basic(username, password) => { holder.withAuth(username, password.getOrElse(""), play.api.libs.ws.WSAuthScheme.BASIC) @@ -519,30 +580,32 @@ package io.apibuilder.task.v0 { requestHeaders: Seq[(String, String)] = Nil, body: Option[play.api.libs.json.JsValue] = None ): scala.concurrent.Future[play.api.libs.ws.WSResponse] = { + import play.api.libs.ws.WSBodyWritables.writeableOf_JsValue + method.toUpperCase match { case "GET" => { - _logRequest("GET", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).get() + _logRequest("GET", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).get() } case "POST" => { - _logRequest("POST", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders): _*).addQueryStringParameters(queryParameters: _*)).post(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("POST", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders)*).addQueryStringParameters(queryParameters*)).post(body.getOrElse(play.api.libs.json.Json.obj())) } case "PUT" => { - _logRequest("PUT", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders): _*).addQueryStringParameters(queryParameters: _*)).put(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("PUT", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders)*).addQueryStringParameters(queryParameters*)).put(body.getOrElse(play.api.libs.json.Json.obj())) } case "PATCH" => { - _logRequest("PATCH", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).patch(body.getOrElse(play.api.libs.json.Json.obj())) + _logRequest("PATCH", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).patch(body.getOrElse(play.api.libs.json.Json.obj())) } case "DELETE" => { - _logRequest("DELETE", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).delete() + _logRequest("DELETE", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).delete() } case "HEAD" => { - _logRequest("HEAD", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).head() + _logRequest("HEAD", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).head() } case "OPTIONS" => { - _logRequest("OPTIONS", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).options() + _logRequest("OPTIONS", _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)).options() } case _ => { - _logRequest(method, _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)) + _logRequest(method, _requestHolder(path).addHttpHeaders(requestHeaders*).addQueryStringParameters(queryParameters*)) sys.error("Unsupported method[%s]".format(method)) } } diff --git a/generated/app/ApicollectiveApibuilderTaskV0MockClient.scala b/generated/app/ApicollectiveApibuilderTaskV0MockClient.scala index b47ce8414..c8af7adc1 100644 --- a/generated/app/ApicollectiveApibuilderTaskV0MockClient.scala +++ b/generated/app/ApicollectiveApibuilderTaskV0MockClient.scala @@ -1,7 +1,7 @@ /** * Generated by API Builder - https://www.apibuilder.io - * Service version: 0.16.43 - * apibuilder app.apibuilder.io/apicollective/apibuilder-task/latest/play_2_8_mock_client + * Service version: 0.16.50 + * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-task/latest/play_2_8_mock_client */ package io.apibuilder.task.v0.mock { diff --git a/lib/src/main/scala/Kind.scala b/lib/src/main/scala/Kind.scala index 366aa5a89..207fc07c9 100644 --- a/lib/src/main/scala/Kind.scala +++ b/lib/src/main/scala/Kind.scala @@ -60,7 +60,7 @@ case class DatatypeResolver( } } } - }) ++ interfaceNames.find(_ == name).map(Kind.Interface).toSeq + }) ++ interfaceNames.find(_ == name).map(Kind.Interface(_)).toSeq } } diff --git a/lib/src/main/scala/generated/ApicollectiveApibuilderSpecV0Models.scala b/lib/src/main/scala/generated/ApicollectiveApibuilderSpecV0Models.scala new file mode 100644 index 000000000..36564f7fb --- /dev/null +++ b/lib/src/main/scala/generated/ApicollectiveApibuilderSpecV0Models.scala @@ -0,0 +1,1416 @@ +/** + * Generated by API Builder - https://www.apibuilder.io + * Service version: 0.16.50 + * User agent: apibuilder app.apibuilder.io/apicollective/apibuilder-spec/latest/play_2_x_standalone_json + */ +package io.apibuilder.spec.v0.models { + + sealed trait ResponseCode extends _root_.scala.Product with _root_.scala.Serializable + /** + * Used to indicate an API concern for a field that is specific to the field's + * usage but not necessarily its data type. For example, you might use annotations + * to mark that certain fields contain PII or PCI data and thus should not be + * stored once processing is complete. Annotations communicate meaning to consumers + * of an API and may also be used within an implementation or tooling; for example, + * using static analysis tools to detect logging of sensitive data. + */ + + final case class Annotation( + name: String, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None + ) + + final case class Apidoc( + version: String + ) + + /** + * @param key Unique key identifying this application + */ + + final case class Application( + key: String + ) + + /** + * Represents an additional attribute that is attached to one of the objects in + * apibuilder. The main use case is to capture additional metadata that doesn't + * necessarily define the API but aids in code generation. Examples would be hints + * for certain code generators about classes to extend, interfaces to implement, + * annotations to add, names to assign to certain methods, etc. The specific + * attributes will be applicable only in the context of the specific code + * generators usings them. + */ + + final case class Attribute( + name: String, + value: _root_.play.api.libs.json.JsObject, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None + ) + + final case class Body( + `type`: String, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, + attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil + ) + + /** + * Describes the primary contact for this service + */ + + final case class Contact( + name: _root_.scala.Option[String] = None, + url: _root_.scala.Option[String] = None, + email: _root_.scala.Option[String] = None + ) + + /** + * Indicates that this particular element is considered deprecated in the API. See + * the description for details + */ + + final case class Deprecation( + description: _root_.scala.Option[String] = None + ) + + final case class Enum( + name: String, + plural: String, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, + values: Seq[io.apibuilder.spec.v0.models.EnumValue], + attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil + ) + + /** + * @param value The actual string representation of this value. If not specified, defaults to + * 'name' + */ + + final case class EnumValue( + name: String, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, + attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil, + value: _root_.scala.Option[String] = None + ) + + final case class Field( + name: String, + `type`: String, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, + default: _root_.scala.Option[String] = None, + required: Boolean, + minimum: _root_.scala.Option[Long] = None, + maximum: _root_.scala.Option[Long] = None, + example: _root_.scala.Option[String] = None, + attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil, + annotations: Seq[String] = Nil + ) + + final case class Header( + name: String, + `type`: String, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, + required: Boolean, + default: _root_.scala.Option[String] = None, + attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil + ) + + /** + * An import is used to declare a dependency on another application. This allows + * you to reference the models and or enums from that application in your own app. + * + * @param uri Full URI to the service.json file of the service we are importing + * @param namespace the fully qualified namespace that we have imported + * @param version The version of the service that we are importing + * @param enums Enums made available by this import + * @param interfaces Interfaces made available by this import + * @param unions Unions made available by this import + * @param models Models made available by this import + * @param annotations Annotations made available by this import + */ + + final case class Import( + uri: String, + namespace: String, + organization: io.apibuilder.spec.v0.models.Organization, + application: io.apibuilder.spec.v0.models.Application, + version: String, + enums: Seq[String] = Nil, + interfaces: Seq[String] = Nil, + unions: Seq[String] = Nil, + models: Seq[String] = Nil, + annotations: Seq[io.apibuilder.spec.v0.models.Annotation] = Nil + ) + + /** + * General metadata about this service + */ + + final case class Info( + license: _root_.scala.Option[io.apibuilder.spec.v0.models.License] = None, + contact: _root_.scala.Option[io.apibuilder.spec.v0.models.Contact] = None + ) + + final case class Interface( + name: String, + plural: String, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, + fields: Seq[io.apibuilder.spec.v0.models.Field], + attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil + ) + + /** + * Describes the software license contact for this service + */ + + final case class License( + name: String, + url: _root_.scala.Option[String] = None + ) + + final case class Model( + name: String, + plural: String, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, + fields: Seq[io.apibuilder.spec.v0.models.Field], + attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil, + interfaces: Seq[String] = Nil + ) + + /** + * @param path The full path to this operation, relative to the service's base url. + */ + + final case class Operation( + method: io.apibuilder.spec.v0.models.Method, + path: String, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, + body: _root_.scala.Option[io.apibuilder.spec.v0.models.Body] = None, + parameters: Seq[io.apibuilder.spec.v0.models.Parameter] = Nil, + responses: Seq[io.apibuilder.spec.v0.models.Response] = Nil, + attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil + ) + + /** + * @param key Unique key identifying the organization that owns this service + */ + + final case class Organization( + key: String + ) + + final case class Parameter( + name: String, + `type`: String, + location: io.apibuilder.spec.v0.models.ParameterLocation, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, + required: Boolean, + default: _root_.scala.Option[String] = None, + minimum: _root_.scala.Option[Long] = None, + maximum: _root_.scala.Option[Long] = None, + example: _root_.scala.Option[String] = None, + attributes: _root_.scala.Option[Seq[io.apibuilder.spec.v0.models.Attribute]] = None + ) + + /** + * @param `type` The type of this resource will map to a defined model, enum, or union type + * @param path The path to this specific resource. This was added in 2016 to help us + * differentiate between the resource path and the operation path which can be + * helpful when, for example, generating method names for operations. This field is + * optional as some of our input formats (e.g. swagger) do not explicitly + * differentiate resoure paths. + */ + + final case class Resource( + `type`: String, + plural: String, + path: _root_.scala.Option[String] = None, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, + operations: Seq[io.apibuilder.spec.v0.models.Operation], + attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil + ) + + final case class Response( + code: io.apibuilder.spec.v0.models.ResponseCode, + `type`: String, + headers: _root_.scala.Option[Seq[io.apibuilder.spec.v0.models.Header]] = None, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, + attributes: _root_.scala.Option[Seq[io.apibuilder.spec.v0.models.Attribute]] = None + ) + + /** + * @param apidoc Documents that this is an apibuilder document, noting the specific version used. + * Internally the version is then used for backwards compatibility when applicable + * as new features are added to apibuilder. Note naming refers to the original name + * of this project, 'apidoc', and is left here to avoid a breaking change for + * preexisting services. + * @param namespace Fully qualified namespace for this service + */ + + final case class Service( + @deprecated("This field is no longer used in API Builder and may be removed in the future.") apidoc: _root_.scala.Option[io.apibuilder.spec.v0.models.Apidoc] = None, + name: String, + organization: io.apibuilder.spec.v0.models.Organization, + application: io.apibuilder.spec.v0.models.Application, + namespace: String, + version: String, + baseUrl: _root_.scala.Option[String] = None, + description: _root_.scala.Option[String] = None, + info: io.apibuilder.spec.v0.models.Info, + headers: Seq[io.apibuilder.spec.v0.models.Header] = Nil, + imports: Seq[io.apibuilder.spec.v0.models.Import] = Nil, + enums: Seq[io.apibuilder.spec.v0.models.Enum] = Nil, + interfaces: Seq[io.apibuilder.spec.v0.models.Interface] = Nil, + unions: Seq[io.apibuilder.spec.v0.models.Union] = Nil, + models: Seq[io.apibuilder.spec.v0.models.Model] = Nil, + resources: Seq[io.apibuilder.spec.v0.models.Resource] = Nil, + attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil, + annotations: Seq[io.apibuilder.spec.v0.models.Annotation] = Nil + ) + + /** + * @param discriminator If a type discriminator is provided, serialization of these union types will + * always contain a field named with the value of the discriminator that will + * contain the name of the type. This provides a simpler (for many use cases) JSON + * serialization/deserialization mechanism. When specified, apibuilder itself will + * verify that none of the types in the union type itself contain a field with the + * same name as the discriminator + * @param types The names of the types that make up this union type + */ + + final case class Union( + name: String, + plural: String, + discriminator: _root_.scala.Option[String] = None, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, + types: Seq[io.apibuilder.spec.v0.models.UnionType], + attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil, + interfaces: Seq[String] = Nil + ) + + /** + * Metadata about one of the types that is part of a union type + * + * @param `type` The name of a type (a primitive, model name, or enum name) that makes up this + * union type + * @param default If true, indicates that this type should be used as the default when + * deserializing union types. This field is only used by union types that require a + * discriminator and sets the default value for that discriminator during + * deserialization. + * @param discriminatorValue The discriminator value defines the string to use in the discriminator field to + * identify this type. If not specified, the discriminator value will default to + * the name of the type itself. + */ + + final case class UnionType( + `type`: String, + description: _root_.scala.Option[String] = None, + deprecation: _root_.scala.Option[io.apibuilder.spec.v0.models.Deprecation] = None, + attributes: Seq[io.apibuilder.spec.v0.models.Attribute] = Nil, + default: _root_.scala.Option[Boolean] = None, + discriminatorValue: _root_.scala.Option[String] = None + ) + + /** + * Provides future compatibility in clients - in the future, when a type is added + * to the union ResponseCode, it will need to be handled in the client code. This + * implementation will deserialize these future types as an instance of this class. + * + * @param description Information about the type that we received that is undefined in this version of + * the client. + */ + + final case class ResponseCodeUndefinedType( + description: String + ) extends ResponseCode + + /** + * Wrapper class to support the union types containing the datatype[integer] + */ + + final case class ResponseCodeInt( + value: Int + ) extends ResponseCode + + sealed trait Method extends _root_.scala.Product with _root_.scala.Serializable + + object Method { + + case object Get extends Method { override def toString = "GET" } + case object Post extends Method { override def toString = "POST" } + case object Put extends Method { override def toString = "PUT" } + case object Patch extends Method { override def toString = "PATCH" } + case object Delete extends Method { override def toString = "DELETE" } + case object Head extends Method { override def toString = "HEAD" } + case object Connect extends Method { override def toString = "CONNECT" } + case object Options extends Method { override def toString = "OPTIONS" } + case object Trace extends Method { override def toString = "TRACE" } + /** + * UNDEFINED captures values that are sent either in error or + * that were added by the server after this library was + * generated. We want to make it easy and obvious for users of + * this library to handle this case gracefully. + * + * We use all CAPS for the variable name to avoid collisions + * with the camel cased values above. + */ + final case class UNDEFINED(override val toString: String) extends Method + + /** + * all returns a list of all the valid, known values. We use + * lower case to avoid collisions with the camel cased values + * above. + */ + val all: scala.List[Method] = scala.List(Get, Post, Put, Patch, Delete, Head, Connect, Options, Trace) + + private + val byName: Map[String, Method] = all.map(x => x.toString.toLowerCase -> x).toMap + + def apply(value: String): Method = fromString(value).getOrElse(UNDEFINED(value)) + + def fromString(value: String): _root_.scala.Option[Method] = byName.get(value.toLowerCase) + + } + + sealed trait ParameterLocation extends _root_.scala.Product with _root_.scala.Serializable + + object ParameterLocation { + + case object Path extends ParameterLocation { override def toString = "Path" } + case object Query extends ParameterLocation { override def toString = "Query" } + case object Form extends ParameterLocation { override def toString = "Form" } + case object Header extends ParameterLocation { override def toString = "Header" } + /** + * UNDEFINED captures values that are sent either in error or + * that were added by the server after this library was + * generated. We want to make it easy and obvious for users of + * this library to handle this case gracefully. + * + * We use all CAPS for the variable name to avoid collisions + * with the camel cased values above. + */ + final case class UNDEFINED(override val toString: String) extends ParameterLocation + + /** + * all returns a list of all the valid, known values. We use + * lower case to avoid collisions with the camel cased values + * above. + */ + val all: scala.List[ParameterLocation] = scala.List(Path, Query, Form, Header) + + private + val byName: Map[String, ParameterLocation] = all.map(x => x.toString.toLowerCase -> x).toMap + + def apply(value: String): ParameterLocation = fromString(value).getOrElse(UNDEFINED(value)) + + def fromString(value: String): _root_.scala.Option[ParameterLocation] = byName.get(value.toLowerCase) + + } + + sealed trait ResponseCodeOption extends ResponseCode + + object ResponseCodeOption { + + case object Default extends ResponseCodeOption { override def toString = "Default" } + /** + * UNDEFINED captures values that are sent either in error or + * that were added by the server after this library was + * generated. We want to make it easy and obvious for users of + * this library to handle this case gracefully. + * + * We use all CAPS for the variable name to avoid collisions + * with the camel cased values above. + */ + final case class UNDEFINED(override val toString: String) extends ResponseCodeOption + + /** + * all returns a list of all the valid, known values. We use + * lower case to avoid collisions with the camel cased values + * above. + */ + val all: scala.List[ResponseCodeOption] = scala.List(Default) + + private + val byName: Map[String, ResponseCodeOption] = all.map(x => x.toString.toLowerCase -> x).toMap + + def apply(value: String): ResponseCodeOption = fromString(value).getOrElse(UNDEFINED(value)) + + def fromString(value: String): _root_.scala.Option[ResponseCodeOption] = byName.get(value.toLowerCase) + + } + +} + +package io.apibuilder.spec.v0.models { + + package object json { + import play.api.libs.json.__ + import play.api.libs.json.JsString + import play.api.libs.json.Writes + import play.api.libs.functional.syntax._ + import io.apibuilder.spec.v0.models.json._ + + private[v0] implicit val jsonReadsUUID: play.api.libs.json.Reads[_root_.java.util.UUID] = __.read[String].map { str => + _root_.java.util.UUID.fromString(str) + } + + private[v0] implicit val jsonWritesUUID: play.api.libs.json.Writes[_root_.java.util.UUID] = (x: _root_.java.util.UUID) => play.api.libs.json.JsString(x.toString) + + private[v0] implicit val jsonReadsJodaDateTime: play.api.libs.json.Reads[_root_.org.joda.time.DateTime] = __.read[String].map { str => + _root_.org.joda.time.format.ISODateTimeFormat.dateTimeParser.parseDateTime(str) + } + + private[v0] implicit val jsonWritesJodaDateTime: play.api.libs.json.Writes[_root_.org.joda.time.DateTime] = (x: _root_.org.joda.time.DateTime) => { + play.api.libs.json.JsString(_root_.org.joda.time.format.ISODateTimeFormat.dateTime.print(x)) + } + + private[v0] implicit val jsonReadsJodaLocalDate: play.api.libs.json.Reads[_root_.org.joda.time.LocalDate] = __.read[String].map { str => + _root_.org.joda.time.format.ISODateTimeFormat.dateTimeParser.parseLocalDate(str) + } + + private[v0] implicit val jsonWritesJodaLocalDate: play.api.libs.json.Writes[_root_.org.joda.time.LocalDate] = (x: _root_.org.joda.time.LocalDate) => { + play.api.libs.json.JsString(_root_.org.joda.time.format.ISODateTimeFormat.date.print(x)) + } + + implicit val jsonReadsApibuilderSpecMethod: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Method] = new play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Method] { + def reads(js: play.api.libs.json.JsValue): play.api.libs.json.JsResult[io.apibuilder.spec.v0.models.Method] = { + js match { + case v: play.api.libs.json.JsString => play.api.libs.json.JsSuccess(io.apibuilder.spec.v0.models.Method(v.value)) + case _ => { + (js \ "value").validate[String] match { + case play.api.libs.json.JsSuccess(v, _) => play.api.libs.json.JsSuccess(io.apibuilder.spec.v0.models.Method(v)) + case err: play.api.libs.json.JsError => + (js \ "method").validate[String] match { + case play.api.libs.json.JsSuccess(v, _) => play.api.libs.json.JsSuccess(io.apibuilder.spec.v0.models.Method(v)) + case err: play.api.libs.json.JsError => err + } + } + } + } + } + } + + def jsonWritesApibuilderSpecMethod(obj: io.apibuilder.spec.v0.models.Method) = { + play.api.libs.json.JsString(obj.toString) + } + + def jsObjectMethod(obj: io.apibuilder.spec.v0.models.Method) = { + play.api.libs.json.Json.obj("value" -> play.api.libs.json.JsString(obj.toString)) + } + + implicit def jsonWritesApibuilderSpecMethod: play.api.libs.json.Writes[Method] = { + (obj: io.apibuilder.spec.v0.models.Method) => { + io.apibuilder.spec.v0.models.json.jsonWritesApibuilderSpecMethod(obj) + } + } + + implicit val jsonReadsApibuilderSpecParameterLocation: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.ParameterLocation] = new play.api.libs.json.Reads[io.apibuilder.spec.v0.models.ParameterLocation] { + def reads(js: play.api.libs.json.JsValue): play.api.libs.json.JsResult[io.apibuilder.spec.v0.models.ParameterLocation] = { + js match { + case v: play.api.libs.json.JsString => play.api.libs.json.JsSuccess(io.apibuilder.spec.v0.models.ParameterLocation(v.value)) + case _ => { + (js \ "value").validate[String] match { + case play.api.libs.json.JsSuccess(v, _) => play.api.libs.json.JsSuccess(io.apibuilder.spec.v0.models.ParameterLocation(v)) + case err: play.api.libs.json.JsError => + (js \ "parameter_location").validate[String] match { + case play.api.libs.json.JsSuccess(v, _) => play.api.libs.json.JsSuccess(io.apibuilder.spec.v0.models.ParameterLocation(v)) + case err: play.api.libs.json.JsError => err + } + } + } + } + } + } + + def jsonWritesApibuilderSpecParameterLocation(obj: io.apibuilder.spec.v0.models.ParameterLocation) = { + play.api.libs.json.JsString(obj.toString) + } + + def jsObjectParameterLocation(obj: io.apibuilder.spec.v0.models.ParameterLocation) = { + play.api.libs.json.Json.obj("value" -> play.api.libs.json.JsString(obj.toString)) + } + + implicit def jsonWritesApibuilderSpecParameterLocation: play.api.libs.json.Writes[ParameterLocation] = { + (obj: io.apibuilder.spec.v0.models.ParameterLocation) => { + io.apibuilder.spec.v0.models.json.jsonWritesApibuilderSpecParameterLocation(obj) + } + } + + implicit val jsonReadsApibuilderSpecResponseCodeOption: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.ResponseCodeOption] = new play.api.libs.json.Reads[io.apibuilder.spec.v0.models.ResponseCodeOption] { + def reads(js: play.api.libs.json.JsValue): play.api.libs.json.JsResult[io.apibuilder.spec.v0.models.ResponseCodeOption] = { + js match { + case v: play.api.libs.json.JsString => play.api.libs.json.JsSuccess(io.apibuilder.spec.v0.models.ResponseCodeOption(v.value)) + case _ => { + (js \ "value").validate[String] match { + case play.api.libs.json.JsSuccess(v, _) => play.api.libs.json.JsSuccess(io.apibuilder.spec.v0.models.ResponseCodeOption(v)) + case err: play.api.libs.json.JsError => + (js \ "response_code_option").validate[String] match { + case play.api.libs.json.JsSuccess(v, _) => play.api.libs.json.JsSuccess(io.apibuilder.spec.v0.models.ResponseCodeOption(v)) + case err: play.api.libs.json.JsError => err + } + } + } + } + } + } + + def jsonWritesApibuilderSpecResponseCodeOption(obj: io.apibuilder.spec.v0.models.ResponseCodeOption) = { + play.api.libs.json.JsString(obj.toString) + } + + def jsObjectResponseCodeOption(obj: io.apibuilder.spec.v0.models.ResponseCodeOption) = { + play.api.libs.json.Json.obj("value" -> play.api.libs.json.JsString(obj.toString)) + } + + implicit def jsonWritesApibuilderSpecResponseCodeOption: play.api.libs.json.Writes[ResponseCodeOption] = { + (obj: io.apibuilder.spec.v0.models.ResponseCodeOption) => { + io.apibuilder.spec.v0.models.json.jsonWritesApibuilderSpecResponseCodeOption(obj) + } + } + + implicit def jsonReadsApibuilderSpecAnnotation: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Annotation] = { + for { + name <- (__ \ "name").read[String] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + } yield Annotation(name, description, deprecation) + } + + def jsObjectAnnotation(obj: io.apibuilder.spec.v0.models.Annotation): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "name" -> play.api.libs.json.JsString(obj.name) + ) ++ (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) + } + + implicit def jsonWritesApibuilderSpecAnnotation: play.api.libs.json.Writes[Annotation] = { + (obj: io.apibuilder.spec.v0.models.Annotation) => { + io.apibuilder.spec.v0.models.json.jsObjectAnnotation(obj) + } + } + + implicit def jsonReadsApibuilderSpecApidoc: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Apidoc] = { + (__ \ "version").read[String].map { x => Apidoc(version = x) } + } + + def jsObjectApidoc(obj: io.apibuilder.spec.v0.models.Apidoc): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "version" -> play.api.libs.json.JsString(obj.version) + ) + } + + implicit def jsonWritesApibuilderSpecApidoc: play.api.libs.json.Writes[Apidoc] = { + (obj: io.apibuilder.spec.v0.models.Apidoc) => { + io.apibuilder.spec.v0.models.json.jsObjectApidoc(obj) + } + } + + implicit def jsonReadsApibuilderSpecApplication: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Application] = { + (__ \ "key").read[String].map { x => Application(key = x) } + } + + def jsObjectApplication(obj: io.apibuilder.spec.v0.models.Application): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "key" -> play.api.libs.json.JsString(obj.key) + ) + } + + implicit def jsonWritesApibuilderSpecApplication: play.api.libs.json.Writes[Application] = { + (obj: io.apibuilder.spec.v0.models.Application) => { + io.apibuilder.spec.v0.models.json.jsObjectApplication(obj) + } + } + + implicit def jsonReadsApibuilderSpecAttribute: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Attribute] = { + for { + name <- (__ \ "name").read[String] + value <- (__ \ "value").read[_root_.play.api.libs.json.JsObject] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + } yield Attribute(name, value, description, deprecation) + } + + def jsObjectAttribute(obj: io.apibuilder.spec.v0.models.Attribute): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "name" -> play.api.libs.json.JsString(obj.name), + "value" -> obj.value + ) ++ (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) + } + + implicit def jsonWritesApibuilderSpecAttribute: play.api.libs.json.Writes[Attribute] = { + (obj: io.apibuilder.spec.v0.models.Attribute) => { + io.apibuilder.spec.v0.models.json.jsObjectAttribute(obj) + } + } + + implicit def jsonReadsApibuilderSpecBody: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Body] = { + for { + `type` <- (__ \ "type").read[String] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + attributes <- (__ \ "attributes").read[Seq[io.apibuilder.spec.v0.models.Attribute]] + } yield Body(`type`, description, deprecation, attributes) + } + + def jsObjectBody(obj: io.apibuilder.spec.v0.models.Body): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "type" -> play.api.libs.json.JsString(obj.`type`), + "attributes" -> play.api.libs.json.Json.toJson(obj.attributes) + ) ++ (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) + } + + implicit def jsonWritesApibuilderSpecBody: play.api.libs.json.Writes[Body] = { + (obj: io.apibuilder.spec.v0.models.Body) => { + io.apibuilder.spec.v0.models.json.jsObjectBody(obj) + } + } + + implicit def jsonReadsApibuilderSpecContact: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Contact] = { + for { + name <- (__ \ "name").readNullable[String] + url <- (__ \ "url").readNullable[String] + email <- (__ \ "email").readNullable[String] + } yield Contact(name, url, email) + } + + def jsObjectContact(obj: io.apibuilder.spec.v0.models.Contact): play.api.libs.json.JsObject = { + (obj.name match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("name" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.url match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("url" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.email match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("email" -> play.api.libs.json.JsString(x)) + }) + } + + implicit def jsonWritesApibuilderSpecContact: play.api.libs.json.Writes[Contact] = { + (obj: io.apibuilder.spec.v0.models.Contact) => { + io.apibuilder.spec.v0.models.json.jsObjectContact(obj) + } + } + + implicit def jsonReadsApibuilderSpecDeprecation: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Deprecation] = { + (__ \ "description").readNullable[String].map { x => Deprecation(description = x) } + } + + def jsObjectDeprecation(obj: io.apibuilder.spec.v0.models.Deprecation): play.api.libs.json.JsObject = { + (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) + } + + implicit def jsonWritesApibuilderSpecDeprecation: play.api.libs.json.Writes[Deprecation] = { + (obj: io.apibuilder.spec.v0.models.Deprecation) => { + io.apibuilder.spec.v0.models.json.jsObjectDeprecation(obj) + } + } + + implicit def jsonReadsApibuilderSpecEnum: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Enum] = { + for { + name <- (__ \ "name").read[String] + plural <- (__ \ "plural").read[String] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + values <- (__ \ "values").read[Seq[io.apibuilder.spec.v0.models.EnumValue]] + attributes <- (__ \ "attributes").read[Seq[io.apibuilder.spec.v0.models.Attribute]] + } yield Enum(name, plural, description, deprecation, values, attributes) + } + + def jsObjectEnum(obj: io.apibuilder.spec.v0.models.Enum): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "name" -> play.api.libs.json.JsString(obj.name), + "plural" -> play.api.libs.json.JsString(obj.plural), + "values" -> play.api.libs.json.Json.toJson(obj.values), + "attributes" -> play.api.libs.json.Json.toJson(obj.attributes) + ) ++ (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) + } + + implicit def jsonWritesApibuilderSpecEnum: play.api.libs.json.Writes[Enum] = { + (obj: io.apibuilder.spec.v0.models.Enum) => { + io.apibuilder.spec.v0.models.json.jsObjectEnum(obj) + } + } + + implicit def jsonReadsApibuilderSpecEnumValue: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.EnumValue] = { + for { + name <- (__ \ "name").read[String] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + attributes <- (__ \ "attributes").read[Seq[io.apibuilder.spec.v0.models.Attribute]] + value <- (__ \ "value").readNullable[String] + } yield EnumValue(name, description, deprecation, attributes, value) + } + + def jsObjectEnumValue(obj: io.apibuilder.spec.v0.models.EnumValue): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "name" -> play.api.libs.json.JsString(obj.name), + "attributes" -> play.api.libs.json.Json.toJson(obj.attributes) + ) ++ (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) ++ + (obj.value match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("value" -> play.api.libs.json.JsString(x)) + }) + } + + implicit def jsonWritesApibuilderSpecEnumValue: play.api.libs.json.Writes[EnumValue] = { + (obj: io.apibuilder.spec.v0.models.EnumValue) => { + io.apibuilder.spec.v0.models.json.jsObjectEnumValue(obj) + } + } + + implicit def jsonReadsApibuilderSpecField: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Field] = { + for { + name <- (__ \ "name").read[String] + `type` <- (__ \ "type").read[String] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + default <- (__ \ "default").readNullable[String] + required <- (__ \ "required").read[Boolean] + minimum <- (__ \ "minimum").readNullable[Long] + maximum <- (__ \ "maximum").readNullable[Long] + example <- (__ \ "example").readNullable[String] + attributes <- (__ \ "attributes").read[Seq[io.apibuilder.spec.v0.models.Attribute]] + annotations <- (__ \ "annotations").readWithDefault[Seq[String]](Nil) + } yield Field(name, `type`, description, deprecation, default, required, minimum, maximum, example, attributes, annotations) + } + + def jsObjectField(obj: io.apibuilder.spec.v0.models.Field): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "name" -> play.api.libs.json.JsString(obj.name), + "type" -> play.api.libs.json.JsString(obj.`type`), + "required" -> play.api.libs.json.JsBoolean(obj.required), + "attributes" -> play.api.libs.json.Json.toJson(obj.attributes), + "annotations" -> play.api.libs.json.Json.toJson(obj.annotations) + ) ++ (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) ++ + (obj.default match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("default" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.minimum match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("minimum" -> play.api.libs.json.JsNumber(x)) + }) ++ + (obj.maximum match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("maximum" -> play.api.libs.json.JsNumber(x)) + }) ++ + (obj.example match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("example" -> play.api.libs.json.JsString(x)) + }) + } + + implicit def jsonWritesApibuilderSpecField: play.api.libs.json.Writes[Field] = { + (obj: io.apibuilder.spec.v0.models.Field) => { + io.apibuilder.spec.v0.models.json.jsObjectField(obj) + } + } + + implicit def jsonReadsApibuilderSpecHeader: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Header] = { + for { + name <- (__ \ "name").read[String] + `type` <- (__ \ "type").read[String] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + required <- (__ \ "required").read[Boolean] + default <- (__ \ "default").readNullable[String] + attributes <- (__ \ "attributes").read[Seq[io.apibuilder.spec.v0.models.Attribute]] + } yield Header(name, `type`, description, deprecation, required, default, attributes) + } + + def jsObjectHeader(obj: io.apibuilder.spec.v0.models.Header): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "name" -> play.api.libs.json.JsString(obj.name), + "type" -> play.api.libs.json.JsString(obj.`type`), + "required" -> play.api.libs.json.JsBoolean(obj.required), + "attributes" -> play.api.libs.json.Json.toJson(obj.attributes) + ) ++ (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) ++ + (obj.default match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("default" -> play.api.libs.json.JsString(x)) + }) + } + + implicit def jsonWritesApibuilderSpecHeader: play.api.libs.json.Writes[Header] = { + (obj: io.apibuilder.spec.v0.models.Header) => { + io.apibuilder.spec.v0.models.json.jsObjectHeader(obj) + } + } + + implicit def jsonReadsApibuilderSpecImport: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Import] = { + for { + uri <- (__ \ "uri").read[String] + namespace <- (__ \ "namespace").read[String] + organization <- (__ \ "organization").read[io.apibuilder.spec.v0.models.Organization] + application <- (__ \ "application").read[io.apibuilder.spec.v0.models.Application] + version <- (__ \ "version").read[String] + enums <- (__ \ "enums").read[Seq[String]] + interfaces <- (__ \ "interfaces").readWithDefault[Seq[String]](Nil) + unions <- (__ \ "unions").read[Seq[String]] + models <- (__ \ "models").read[Seq[String]] + annotations <- (__ \ "annotations").readWithDefault[Seq[io.apibuilder.spec.v0.models.Annotation]](Nil) + } yield Import(uri, namespace, organization, application, version, enums, interfaces, unions, models, annotations) + } + + def jsObjectImport(obj: io.apibuilder.spec.v0.models.Import): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "uri" -> play.api.libs.json.JsString(obj.uri), + "namespace" -> play.api.libs.json.JsString(obj.namespace), + "organization" -> io.apibuilder.spec.v0.models.json.jsObjectOrganization(obj.organization), + "application" -> io.apibuilder.spec.v0.models.json.jsObjectApplication(obj.application), + "version" -> play.api.libs.json.JsString(obj.version), + "enums" -> play.api.libs.json.Json.toJson(obj.enums), + "interfaces" -> play.api.libs.json.Json.toJson(obj.interfaces), + "unions" -> play.api.libs.json.Json.toJson(obj.unions), + "models" -> play.api.libs.json.Json.toJson(obj.models), + "annotations" -> play.api.libs.json.Json.toJson(obj.annotations) + ) + } + + implicit def jsonWritesApibuilderSpecImport: play.api.libs.json.Writes[Import] = { + (obj: io.apibuilder.spec.v0.models.Import) => { + io.apibuilder.spec.v0.models.json.jsObjectImport(obj) + } + } + + implicit def jsonReadsApibuilderSpecInfo: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Info] = { + for { + license <- (__ \ "license").readNullable[io.apibuilder.spec.v0.models.License] + contact <- (__ \ "contact").readNullable[io.apibuilder.spec.v0.models.Contact] + } yield Info(license, contact) + } + + def jsObjectInfo(obj: io.apibuilder.spec.v0.models.Info): play.api.libs.json.JsObject = { + (obj.license match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("license" -> io.apibuilder.spec.v0.models.json.jsObjectLicense(x)) + }) ++ + (obj.contact match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("contact" -> io.apibuilder.spec.v0.models.json.jsObjectContact(x)) + }) + } + + implicit def jsonWritesApibuilderSpecInfo: play.api.libs.json.Writes[Info] = { + (obj: io.apibuilder.spec.v0.models.Info) => { + io.apibuilder.spec.v0.models.json.jsObjectInfo(obj) + } + } + + implicit def jsonReadsApibuilderSpecInterface: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Interface] = { + for { + name <- (__ \ "name").read[String] + plural <- (__ \ "plural").read[String] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + fields <- (__ \ "fields").read[Seq[io.apibuilder.spec.v0.models.Field]] + attributes <- (__ \ "attributes").read[Seq[io.apibuilder.spec.v0.models.Attribute]] + } yield Interface(name, plural, description, deprecation, fields, attributes) + } + + def jsObjectInterface(obj: io.apibuilder.spec.v0.models.Interface): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "name" -> play.api.libs.json.JsString(obj.name), + "plural" -> play.api.libs.json.JsString(obj.plural), + "fields" -> play.api.libs.json.Json.toJson(obj.fields), + "attributes" -> play.api.libs.json.Json.toJson(obj.attributes) + ) ++ (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) + } + + implicit def jsonWritesApibuilderSpecInterface: play.api.libs.json.Writes[Interface] = { + (obj: io.apibuilder.spec.v0.models.Interface) => { + io.apibuilder.spec.v0.models.json.jsObjectInterface(obj) + } + } + + implicit def jsonReadsApibuilderSpecLicense: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.License] = { + for { + name <- (__ \ "name").read[String] + url <- (__ \ "url").readNullable[String] + } yield License(name, url) + } + + def jsObjectLicense(obj: io.apibuilder.spec.v0.models.License): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "name" -> play.api.libs.json.JsString(obj.name) + ) ++ (obj.url match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("url" -> play.api.libs.json.JsString(x)) + }) + } + + implicit def jsonWritesApibuilderSpecLicense: play.api.libs.json.Writes[License] = { + (obj: io.apibuilder.spec.v0.models.License) => { + io.apibuilder.spec.v0.models.json.jsObjectLicense(obj) + } + } + + implicit def jsonReadsApibuilderSpecModel: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Model] = { + for { + name <- (__ \ "name").read[String] + plural <- (__ \ "plural").read[String] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + fields <- (__ \ "fields").read[Seq[io.apibuilder.spec.v0.models.Field]] + attributes <- (__ \ "attributes").read[Seq[io.apibuilder.spec.v0.models.Attribute]] + interfaces <- (__ \ "interfaces").readWithDefault[Seq[String]](Nil) + } yield Model(name, plural, description, deprecation, fields, attributes, interfaces) + } + + def jsObjectModel(obj: io.apibuilder.spec.v0.models.Model): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "name" -> play.api.libs.json.JsString(obj.name), + "plural" -> play.api.libs.json.JsString(obj.plural), + "fields" -> play.api.libs.json.Json.toJson(obj.fields), + "attributes" -> play.api.libs.json.Json.toJson(obj.attributes), + "interfaces" -> play.api.libs.json.Json.toJson(obj.interfaces) + ) ++ (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) + } + + implicit def jsonWritesApibuilderSpecModel: play.api.libs.json.Writes[Model] = { + (obj: io.apibuilder.spec.v0.models.Model) => { + io.apibuilder.spec.v0.models.json.jsObjectModel(obj) + } + } + + implicit def jsonReadsApibuilderSpecOperation: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Operation] = { + for { + method <- (__ \ "method").read[io.apibuilder.spec.v0.models.Method] + path <- (__ \ "path").read[String] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + body <- (__ \ "body").readNullable[io.apibuilder.spec.v0.models.Body] + parameters <- (__ \ "parameters").read[Seq[io.apibuilder.spec.v0.models.Parameter]] + responses <- (__ \ "responses").read[Seq[io.apibuilder.spec.v0.models.Response]] + attributes <- (__ \ "attributes").read[Seq[io.apibuilder.spec.v0.models.Attribute]] + } yield Operation(method, path, description, deprecation, body, parameters, responses, attributes) + } + + def jsObjectOperation(obj: io.apibuilder.spec.v0.models.Operation): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "method" -> play.api.libs.json.JsString(obj.method.toString), + "path" -> play.api.libs.json.JsString(obj.path), + "parameters" -> play.api.libs.json.Json.toJson(obj.parameters), + "responses" -> play.api.libs.json.Json.toJson(obj.responses), + "attributes" -> play.api.libs.json.Json.toJson(obj.attributes) + ) ++ (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) ++ + (obj.body match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("body" -> io.apibuilder.spec.v0.models.json.jsObjectBody(x)) + }) + } + + implicit def jsonWritesApibuilderSpecOperation: play.api.libs.json.Writes[Operation] = { + (obj: io.apibuilder.spec.v0.models.Operation) => { + io.apibuilder.spec.v0.models.json.jsObjectOperation(obj) + } + } + + implicit def jsonReadsApibuilderSpecOrganization: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Organization] = { + (__ \ "key").read[String].map { x => Organization(key = x) } + } + + def jsObjectOrganization(obj: io.apibuilder.spec.v0.models.Organization): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "key" -> play.api.libs.json.JsString(obj.key) + ) + } + + implicit def jsonWritesApibuilderSpecOrganization: play.api.libs.json.Writes[Organization] = { + (obj: io.apibuilder.spec.v0.models.Organization) => { + io.apibuilder.spec.v0.models.json.jsObjectOrganization(obj) + } + } + + implicit def jsonReadsApibuilderSpecParameter: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Parameter] = { + for { + name <- (__ \ "name").read[String] + `type` <- (__ \ "type").read[String] + location <- (__ \ "location").read[io.apibuilder.spec.v0.models.ParameterLocation] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + required <- (__ \ "required").read[Boolean] + default <- (__ \ "default").readNullable[String] + minimum <- (__ \ "minimum").readNullable[Long] + maximum <- (__ \ "maximum").readNullable[Long] + example <- (__ \ "example").readNullable[String] + attributes <- (__ \ "attributes").readNullable[Seq[io.apibuilder.spec.v0.models.Attribute]] + } yield Parameter(name, `type`, location, description, deprecation, required, default, minimum, maximum, example, attributes) + } + + def jsObjectParameter(obj: io.apibuilder.spec.v0.models.Parameter): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "name" -> play.api.libs.json.JsString(obj.name), + "type" -> play.api.libs.json.JsString(obj.`type`), + "location" -> play.api.libs.json.JsString(obj.location.toString), + "required" -> play.api.libs.json.JsBoolean(obj.required) + ) ++ (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) ++ + (obj.default match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("default" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.minimum match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("minimum" -> play.api.libs.json.JsNumber(x)) + }) ++ + (obj.maximum match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("maximum" -> play.api.libs.json.JsNumber(x)) + }) ++ + (obj.example match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("example" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.attributes match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("attributes" -> play.api.libs.json.Json.toJson(x)) + }) + } + + implicit def jsonWritesApibuilderSpecParameter: play.api.libs.json.Writes[Parameter] = { + (obj: io.apibuilder.spec.v0.models.Parameter) => { + io.apibuilder.spec.v0.models.json.jsObjectParameter(obj) + } + } + + implicit def jsonReadsApibuilderSpecResource: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Resource] = { + for { + `type` <- (__ \ "type").read[String] + plural <- (__ \ "plural").read[String] + path <- (__ \ "path").readNullable[String] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + operations <- (__ \ "operations").read[Seq[io.apibuilder.spec.v0.models.Operation]] + attributes <- (__ \ "attributes").read[Seq[io.apibuilder.spec.v0.models.Attribute]] + } yield Resource(`type`, plural, path, description, deprecation, operations, attributes) + } + + def jsObjectResource(obj: io.apibuilder.spec.v0.models.Resource): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "type" -> play.api.libs.json.JsString(obj.`type`), + "plural" -> play.api.libs.json.JsString(obj.plural), + "operations" -> play.api.libs.json.Json.toJson(obj.operations), + "attributes" -> play.api.libs.json.Json.toJson(obj.attributes) + ) ++ (obj.path match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("path" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) + } + + implicit def jsonWritesApibuilderSpecResource: play.api.libs.json.Writes[Resource] = { + (obj: io.apibuilder.spec.v0.models.Resource) => { + io.apibuilder.spec.v0.models.json.jsObjectResource(obj) + } + } + + implicit def jsonReadsApibuilderSpecResponse: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Response] = { + for { + code <- (__ \ "code").read[io.apibuilder.spec.v0.models.ResponseCode] + `type` <- (__ \ "type").read[String] + headers <- (__ \ "headers").readNullable[Seq[io.apibuilder.spec.v0.models.Header]] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + attributes <- (__ \ "attributes").readNullable[Seq[io.apibuilder.spec.v0.models.Attribute]] + } yield Response(code, `type`, headers, description, deprecation, attributes) + } + + def jsObjectResponse(obj: io.apibuilder.spec.v0.models.Response): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "code" -> io.apibuilder.spec.v0.models.json.jsObjectResponseCode(obj.code), + "type" -> play.api.libs.json.JsString(obj.`type`) + ) ++ (obj.headers match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("headers" -> play.api.libs.json.Json.toJson(x)) + }) ++ + (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) ++ + (obj.attributes match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("attributes" -> play.api.libs.json.Json.toJson(x)) + }) + } + + implicit def jsonWritesApibuilderSpecResponse: play.api.libs.json.Writes[Response] = { + (obj: io.apibuilder.spec.v0.models.Response) => { + io.apibuilder.spec.v0.models.json.jsObjectResponse(obj) + } + } + + implicit def jsonReadsApibuilderSpecService: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Service] = { + for { + apidoc <- (__ \ "apidoc").readNullable[io.apibuilder.spec.v0.models.Apidoc] + name <- (__ \ "name").read[String] + organization <- (__ \ "organization").read[io.apibuilder.spec.v0.models.Organization] + application <- (__ \ "application").read[io.apibuilder.spec.v0.models.Application] + namespace <- (__ \ "namespace").read[String] + version <- (__ \ "version").read[String] + baseUrl <- (__ \ "base_url").readNullable[String] + description <- (__ \ "description").readNullable[String] + info <- (__ \ "info").read[io.apibuilder.spec.v0.models.Info] + headers <- (__ \ "headers").read[Seq[io.apibuilder.spec.v0.models.Header]] + imports <- (__ \ "imports").read[Seq[io.apibuilder.spec.v0.models.Import]] + enums <- (__ \ "enums").read[Seq[io.apibuilder.spec.v0.models.Enum]] + interfaces <- (__ \ "interfaces").readWithDefault[Seq[io.apibuilder.spec.v0.models.Interface]](Nil) + unions <- (__ \ "unions").read[Seq[io.apibuilder.spec.v0.models.Union]] + models <- (__ \ "models").read[Seq[io.apibuilder.spec.v0.models.Model]] + resources <- (__ \ "resources").read[Seq[io.apibuilder.spec.v0.models.Resource]] + attributes <- (__ \ "attributes").read[Seq[io.apibuilder.spec.v0.models.Attribute]] + annotations <- (__ \ "annotations").readWithDefault[Seq[io.apibuilder.spec.v0.models.Annotation]](Nil) + } yield Service(apidoc, name, organization, application, namespace, version, baseUrl, description, info, headers, imports, enums, interfaces, unions, models, resources, attributes, annotations) + } + + def jsObjectService(obj: io.apibuilder.spec.v0.models.Service): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "name" -> play.api.libs.json.JsString(obj.name), + "organization" -> io.apibuilder.spec.v0.models.json.jsObjectOrganization(obj.organization), + "application" -> io.apibuilder.spec.v0.models.json.jsObjectApplication(obj.application), + "namespace" -> play.api.libs.json.JsString(obj.namespace), + "version" -> play.api.libs.json.JsString(obj.version), + "info" -> io.apibuilder.spec.v0.models.json.jsObjectInfo(obj.info), + "headers" -> play.api.libs.json.Json.toJson(obj.headers), + "imports" -> play.api.libs.json.Json.toJson(obj.imports), + "enums" -> play.api.libs.json.Json.toJson(obj.enums), + "interfaces" -> play.api.libs.json.Json.toJson(obj.interfaces), + "unions" -> play.api.libs.json.Json.toJson(obj.unions), + "models" -> play.api.libs.json.Json.toJson(obj.models), + "resources" -> play.api.libs.json.Json.toJson(obj.resources), + "attributes" -> play.api.libs.json.Json.toJson(obj.attributes), + "annotations" -> play.api.libs.json.Json.toJson(obj.annotations) + ) ++ (obj.apidoc match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("apidoc" -> io.apibuilder.spec.v0.models.json.jsObjectApidoc(x)) + }) ++ + (obj.baseUrl match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("base_url" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) + } + + implicit def jsonWritesApibuilderSpecService: play.api.libs.json.Writes[Service] = { + (obj: io.apibuilder.spec.v0.models.Service) => { + io.apibuilder.spec.v0.models.json.jsObjectService(obj) + } + } + + implicit def jsonReadsApibuilderSpecUnion: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.Union] = { + for { + name <- (__ \ "name").read[String] + plural <- (__ \ "plural").read[String] + discriminator <- (__ \ "discriminator").readNullable[String] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + types <- (__ \ "types").read[Seq[io.apibuilder.spec.v0.models.UnionType]] + attributes <- (__ \ "attributes").read[Seq[io.apibuilder.spec.v0.models.Attribute]] + interfaces <- (__ \ "interfaces").readWithDefault[Seq[String]](Nil) + } yield Union(name, plural, discriminator, description, deprecation, types, attributes, interfaces) + } + + def jsObjectUnion(obj: io.apibuilder.spec.v0.models.Union): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "name" -> play.api.libs.json.JsString(obj.name), + "plural" -> play.api.libs.json.JsString(obj.plural), + "types" -> play.api.libs.json.Json.toJson(obj.types), + "attributes" -> play.api.libs.json.Json.toJson(obj.attributes), + "interfaces" -> play.api.libs.json.Json.toJson(obj.interfaces) + ) ++ (obj.discriminator match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("discriminator" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) + } + + implicit def jsonWritesApibuilderSpecUnion: play.api.libs.json.Writes[Union] = { + (obj: io.apibuilder.spec.v0.models.Union) => { + io.apibuilder.spec.v0.models.json.jsObjectUnion(obj) + } + } + + implicit def jsonReadsApibuilderSpecUnionType: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.UnionType] = { + for { + `type` <- (__ \ "type").read[String] + description <- (__ \ "description").readNullable[String] + deprecation <- (__ \ "deprecation").readNullable[io.apibuilder.spec.v0.models.Deprecation] + attributes <- (__ \ "attributes").read[Seq[io.apibuilder.spec.v0.models.Attribute]] + default <- (__ \ "default").readNullable[Boolean] + discriminatorValue <- (__ \ "discriminator_value").readNullable[String] + } yield UnionType(`type`, description, deprecation, attributes, default, discriminatorValue) + } + + def jsObjectUnionType(obj: io.apibuilder.spec.v0.models.UnionType): play.api.libs.json.JsObject = { + play.api.libs.json.Json.obj( + "type" -> play.api.libs.json.JsString(obj.`type`), + "attributes" -> play.api.libs.json.Json.toJson(obj.attributes) + ) ++ (obj.description match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("description" -> play.api.libs.json.JsString(x)) + }) ++ + (obj.deprecation match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("deprecation" -> io.apibuilder.spec.v0.models.json.jsObjectDeprecation(x)) + }) ++ + (obj.default match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("default" -> play.api.libs.json.JsBoolean(x)) + }) ++ + (obj.discriminatorValue match { + case None => play.api.libs.json.Json.obj() + case Some(x) => play.api.libs.json.Json.obj("discriminator_value" -> play.api.libs.json.JsString(x)) + }) + } + + implicit def jsonWritesApibuilderSpecUnionType: play.api.libs.json.Writes[UnionType] = { + (obj: io.apibuilder.spec.v0.models.UnionType) => { + io.apibuilder.spec.v0.models.json.jsObjectUnionType(obj) + } + } + + implicit def jsonReadsApibuilderSpecResponseCodeInt: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.ResponseCodeInt] = { + (__ \ "value").read[Int].map { x => ResponseCodeInt(value = x) } + } + + implicit def jsonReadsApibuilderSpecResponseCode: play.api.libs.json.Reads[io.apibuilder.spec.v0.models.ResponseCode] = { + ( + (__ \ "integer").read(jsonReadsApibuilderSpecResponseCodeInt).asInstanceOf[play.api.libs.json.Reads[ResponseCode]] + orElse + (__ \ "response_code_option").read(jsonReadsApibuilderSpecResponseCodeOption).asInstanceOf[play.api.libs.json.Reads[ResponseCode]] + orElse + play.api.libs.json.Reads(jsValue => play.api.libs.json.JsSuccess(ResponseCodeUndefinedType(jsValue.toString))).asInstanceOf[play.api.libs.json.Reads[ResponseCode]] + ) + } + + def jsObjectResponseCode(obj: io.apibuilder.spec.v0.models.ResponseCode): play.api.libs.json.JsObject = { + obj match { + case x: io.apibuilder.spec.v0.models.ResponseCodeInt => play.api.libs.json.Json.obj("integer" -> play.api.libs.json.Json.obj("value" -> play.api.libs.json.JsNumber(x.value))) + case x: io.apibuilder.spec.v0.models.ResponseCodeOption => play.api.libs.json.Json.obj("response_code_option" -> play.api.libs.json.JsString(x.toString)) + case x: io.apibuilder.spec.v0.models.ResponseCodeUndefinedType => sys.error(s"The type[io.apibuilder.spec.v0.models.ResponseCodeUndefinedType] should never be serialized") + } + } + implicit def jsonWritesApibuilderSpecResponseCode: play.api.libs.json.Writes[ResponseCode] = { + (obj: io.apibuilder.spec.v0.models.ResponseCode) => { + io.apibuilder.spec.v0.models.json.jsObjectResponseCode(obj) + } + } + } +} + diff --git a/lib/src/test/scala/helpers/ValidatedTestHelpers.scala b/lib/src/test/scala/helpers/ValidatedTestHelpers.scala index ad202742d..d36b700c5 100644 --- a/lib/src/test/scala/helpers/ValidatedTestHelpers.scala +++ b/lib/src/test/scala/helpers/ValidatedTestHelpers.scala @@ -5,14 +5,14 @@ import cats.data.ValidatedNec trait ValidatedTestHelpers { - def expectValid[T](r: ValidatedNec[_, T]): T = { - r match { - case Valid(o) => o - case Invalid(errors) => sys.error(s"Expected valid but was invalid: ${errors.toNonEmptyList}") + def expectValid[S, T](value: ValidatedNec[S, T]): T = { + value match { + case Invalid(e) => sys.error(s"Expected valid but got: ${e.toNonEmptyList.toList.mkString(", ")}") + case Valid(v) => v } } - def expectInvalid[T](r: ValidatedNec[T, _]): Seq[T] = { + def expectInvalid[T, U](r: ValidatedNec[T, U]): Seq[T] = { r match { case Valid(_) => sys.error("Expected invalid but was valid") case Invalid(errors) => errors.toNonEmptyList.toList diff --git a/project/plugins.sbt b/project/plugins.sbt index d09611587..2954a8aaf 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -7,8 +7,10 @@ resolvers += "Typesafe repository" at "https://repo.typesafe.com/typesafe/releas // Use the Play sbt plugin for Play projects addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.9.4") -addSbtPlugin("com.typesafe.play" % "sbt-twirl" % "1.6.7") +addSbtPlugin("com.typesafe.play" % "sbt-twirl" % "1.6.8") addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.1") addSbtPlugin("com.github.sbt" % "sbt-javaagent" % "0.1.8") + +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") diff --git a/spec/apibuilder-task.json b/spec/apibuilder-task.json index 981ce800f..0ca3c4958 100644 --- a/spec/apibuilder-task.json +++ b/spec/apibuilder-task.json @@ -36,6 +36,7 @@ "unions": { "email_data": { + "discriminator": "discriminator", "types": [ { "type": "email_data_application_created" }, { "type": "email_data_email_verification_created" }, diff --git a/swagger/src/main/scala/io/apibuilder/swagger/Parser.scala b/swagger/src/main/scala/io/apibuilder/swagger/Parser.scala index df83664aa..ed9f541d7 100644 --- a/swagger/src/main/scala/io/apibuilder/swagger/Parser.scala +++ b/swagger/src/main/scala/io/apibuilder/swagger/Parser.scala @@ -229,7 +229,7 @@ case class Parser(config: ServiceConfiguration) { plural = Text.pluralize(enumTypeName), description = None, deprecation = None, - values = param.asInstanceOf[AbstractSerializableParameter[_]].getEnum.asScala.map { value => + values = param.asInstanceOf[AbstractSerializableParameter[?]].getEnum.asScala.map { value => EnumValue(name = value, description = None, deprecation = None, attributes = Seq()) }.toSeq, attributes = Seq(), diff --git a/swagger/src/main/scala/io/apibuilder/swagger/Util.scala b/swagger/src/main/scala/io/apibuilder/swagger/Util.scala index 84891648b..134b7621c 100644 --- a/swagger/src/main/scala/io/apibuilder/swagger/Util.scala +++ b/swagger/src/main/scala/io/apibuilder/swagger/Util.scala @@ -112,7 +112,7 @@ object Util { def hasStringEnum(param: swaggerparams.Parameter): Boolean = { (param.isInstanceOf[swaggerparams.PathParameter] || param.isInstanceOf[swaggerparams.QueryParameter]) && { param match { - case enumerableParam: swaggerparams.AbstractSerializableParameter[_] => + case enumerableParam: swaggerparams.AbstractSerializableParameter[?] => enumerableParam.getType.equals(swaggerproperties.StringProperty.TYPE) && enumerableParam.getEnum != null && !enumerableParam.getEnum.isEmpty diff --git a/swagger/src/main/scala/io/apibuilder/swagger/translators/Field.scala b/swagger/src/main/scala/io/apibuilder/swagger/translators/Field.scala index a94942dc3..f4acea92c 100644 --- a/swagger/src/main/scala/io/apibuilder/swagger/translators/Field.scala +++ b/swagger/src/main/scala/io/apibuilder/swagger/translators/Field.scala @@ -54,7 +54,7 @@ object Field { base.copy( description = Option(p.getUniqueItems()).getOrElse(false) match { case true => Util.combine(Seq(base.description, Some(s"Note: items are unique"))) - case false => base.description + case _ => base.description } ) } diff --git a/swagger/src/main/scala/io/apibuilder/swagger/translators/Model.scala b/swagger/src/main/scala/io/apibuilder/swagger/translators/Model.scala index da388d1fd..cd4da6476 100644 --- a/swagger/src/main/scala/io/apibuilder/swagger/translators/Model.scala +++ b/swagger/src/main/scala/io/apibuilder/swagger/translators/Model.scala @@ -7,13 +7,13 @@ import lib.Text import io.apibuilder.swagger.{SwaggerData, Util} object Model { - val Placeholder: apidoc.Model = apidoc.Model( - name = "placeholder", - plural = "placeholders", - fields = Seq( - apidoc.Field(name = "placeholder", `type` = "string", required=false) - ) - ) + val Placeholder: apidoc.Model = apidoc.Model( + name = "placeholder", + plural = "placeholders", + fields = Seq( + apidoc.Field(name = "placeholder", `type` = "string", required=false) + ) + ) def apply( resolver: Resolver, diff --git a/swagger/src/main/scala/io/apibuilder/swagger/translators/Operation.scala b/swagger/src/main/scala/io/apibuilder/swagger/translators/Operation.scala index 9d9145328..6d3b6f519 100644 --- a/swagger/src/main/scala/io/apibuilder/swagger/translators/Operation.scala +++ b/swagger/src/main/scala/io/apibuilder/swagger/translators/Operation.scala @@ -44,7 +44,7 @@ object Operation { description = Util.combine(Seq(summary, description, ExternalDoc(Option(op.getExternalDocs)))), deprecation = Option(op.isDeprecated).getOrElse(false) match { case false => None - case true => Some(apidoc.Deprecation()) + case _ => Some(apidoc.Deprecation()) }, body = bodies.toList match { case Nil => None diff --git a/swagger/src/test/scala/io/apibuilder/swagger/SwaggerServiceValidatorSpec.scala b/swagger/src/test/scala/io/apibuilder/swagger/SwaggerServiceValidatorSpec.scala index a37f2f896..0428701bf 100644 --- a/swagger/src/test/scala/io/apibuilder/swagger/SwaggerServiceValidatorSpec.scala +++ b/swagger/src/test/scala/io/apibuilder/swagger/SwaggerServiceValidatorSpec.scala @@ -865,7 +865,7 @@ class SwaggerServiceValidatorSpec extends AnyFunSpec with Matchers with Validate filename => val path = resourcesDir + filename println(s"Reading file[$path]") - validate(path) match { + validate(path) match { case Invalid(errors) => { fail(s"Service validation failed for path[$path]: " + formatErrors(errors)) }
@depr
@value.name @value.value.getOrElse(value.name)@Html(lib.Markdown(value.description)) -

- @enum.deprecation.map(deprecation(_)) -

-
@Html(lib.Markdown(value.description))