@autobe/agent 0.30.0-dev.20260315 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -661
- package/lib/constants/AutoBeTemplateFileConstant.d.ts +1 -1
- package/lib/factory/consentFunctionCall.js +4 -4
- package/lib/factory/createAutoBeContext.js +24 -24
- package/lib/factory/createAutoBeMessageContent.js +6 -6
- package/lib/index.mjs +41 -41
- package/lib/orchestrate/analyze/histories/transformAnalyzeScenarioHistory.js +18 -18
- package/lib/orchestrate/analyze/histories/transformAnalyzeScenarioReviewHistory.js +13 -13
- package/lib/orchestrate/analyze/histories/transformAnalyzeSectionCrossFileReviewHistory.js +47 -47
- package/lib/orchestrate/analyze/histories/transformAnalyzeSectionReviewHistory.js +66 -66
- package/lib/orchestrate/analyze/histories/transformAnalyzeWriteSectionHistory.js +91 -91
- package/lib/orchestrate/analyze/histories/transformAnalyzeWriteSectionPatchHistory.js +46 -46
- package/lib/orchestrate/analyze/histories/transformAnalyzeWriteUnitHistory.js +72 -72
- package/lib/orchestrate/analyze/orchestrateAnalyzeScenario.js +1 -1
- package/lib/orchestrate/analyze/orchestrateAnalyzeSectionCrossFileReview.js +1 -1
- package/lib/orchestrate/analyze/orchestrateAnalyzeSectionReview.js +1 -1
- package/lib/orchestrate/analyze/orchestrateAnalyzeWriteSection.js +1 -1
- package/lib/orchestrate/analyze/orchestrateAnalyzeWriteSectionPatch.js +1 -1
- package/lib/orchestrate/analyze/orchestrateAnalyzeWriteUnit.js +1 -1
- package/lib/orchestrate/common/histories/transformCommonCorrectCastingHistory.js +5 -5
- package/lib/orchestrate/common/histories/transformPreliminaryHistory.js +44 -44
- package/lib/orchestrate/common/histories/transformPreviousAndLatestCorrectHistory.js +44 -44
- package/lib/orchestrate/common/internal/fixPrelminaryApplication.js +22 -22
- package/lib/orchestrate/common/internal/validatePreliminary.js +116 -116
- package/lib/orchestrate/facade/createAutoBeFacadeController.js +3 -3
- package/lib/orchestrate/facade/structures/transformFacadeStateMessage.js +20 -20
- package/lib/orchestrate/interface/histories/transformInterfaceActionEndpointReviewHistory.js +34 -34
- package/lib/orchestrate/interface/histories/transformInterfaceActionEndpointWriteHistory.js +37 -37
- package/lib/orchestrate/interface/histories/transformInterfaceAuthorizationHistory.js +56 -56
- package/lib/orchestrate/interface/histories/transformInterfaceBaseEndpointReviewHistory.js +26 -26
- package/lib/orchestrate/interface/histories/transformInterfaceBaseEndpointWriteHistory.js +28 -28
- package/lib/orchestrate/interface/histories/transformInterfaceEndpointAuthorizationSection.js +11 -11
- package/lib/orchestrate/interface/histories/transformInterfaceGroupHistory.js +38 -38
- package/lib/orchestrate/interface/histories/transformInterfaceOperationHistory.js +29 -29
- package/lib/orchestrate/interface/histories/transformInterfaceOperationParameterHistory.js +15 -15
- package/lib/orchestrate/interface/histories/transformInterfaceOperationReviewHistory.js +6 -6
- package/lib/orchestrate/interface/histories/transformInterfacePrerequisiteHistory.js +25 -25
- package/lib/orchestrate/interface/histories/transformInterfaceSchemaCastingHistory.js +67 -67
- package/lib/orchestrate/interface/histories/transformInterfaceSchemaComplementHistory.js +60 -60
- package/lib/orchestrate/interface/histories/transformInterfaceSchemaRefineHistory.js +83 -83
- package/lib/orchestrate/interface/histories/transformInterfaceSchemaRenameHistory.js +29 -29
- package/lib/orchestrate/interface/histories/transformInterfaceSchemaReviewHistory.js +74 -74
- package/lib/orchestrate/interface/histories/transformInterfaceSchemaWriteHistory.js +46 -46
- package/lib/orchestrate/interface/orchestrateInterfaceAuthorization.js +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceEndpointReview.js +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceEndpointWrite.js +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceGroup.js +9 -9
- package/lib/orchestrate/interface/orchestrateInterfaceOperation.js +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceOperationReview.js +1 -1
- package/lib/orchestrate/interface/orchestrateInterfacePrerequisite.js +4 -4
- package/lib/orchestrate/interface/orchestrateInterfaceSchemaCasting.js +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceSchemaComplement.js +5 -5
- package/lib/orchestrate/interface/orchestrateInterfaceSchemaRefine.js +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceSchemaReview.js +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceSchemaWrite.js +1 -1
- package/lib/orchestrate/interface/programmers/AutoBeInterfaceAuthorizationProgrammer.js +90 -90
- package/lib/orchestrate/interface/programmers/AutoBeInterfaceEndpointProgrammer.js +6 -6
- package/lib/orchestrate/interface/programmers/AutoBeInterfaceEndpointReviewProgrammer.js +25 -25
- package/lib/orchestrate/interface/programmers/AutoBeInterfaceOperationProgrammer.js +71 -71
- package/lib/orchestrate/interface/programmers/AutoBeInterfacePrerequisiteProgrammer.js +162 -162
- package/lib/orchestrate/interface/programmers/AutoBeInterfaceSchemaProgrammer.js +11 -11
- package/lib/orchestrate/interface/programmers/AutoBeInterfaceSchemaPropertyReviseProgrammer.js +73 -73
- package/lib/orchestrate/interface/programmers/AutoBeInterfaceSchemaRefineProgrammer.js +35 -35
- package/lib/orchestrate/interface/programmers/AutoBeInterfaceSchemaReviewProgrammer.js +11 -11
- package/lib/orchestrate/interface/utils/AutoBeJsonSchemaFactory.js +4 -4
- package/lib/orchestrate/interface/utils/AutoBeJsonSchemaValidator.js +283 -283
- package/lib/orchestrate/interface/utils/fulfillJsonSchemaErrorMessages.js +76 -76
- package/lib/orchestrate/prisma/histories/transformPrismaAuthorizationHistory.js +76 -76
- package/lib/orchestrate/prisma/histories/transformPrismaAuthorizationReviewHistory.js +51 -51
- package/lib/orchestrate/prisma/histories/transformPrismaComponentReviewHistory.js +54 -54
- package/lib/orchestrate/prisma/histories/transformPrismaComponentsHistory.js +83 -83
- package/lib/orchestrate/prisma/histories/transformPrismaCorrectHistory.js +6 -6
- package/lib/orchestrate/prisma/histories/transformPrismaGroupHistory.js +22 -22
- package/lib/orchestrate/prisma/histories/transformPrismaGroupReviewHistory.js +41 -41
- package/lib/orchestrate/prisma/histories/transformPrismaSchemaHistory.js +39 -39
- package/lib/orchestrate/prisma/histories/transformPrismaSchemaReviewHistory.js +41 -41
- package/lib/orchestrate/prisma/orchestratePrismaAuthorization.js +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaAuthorizationReview.js +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaComponent.js +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaComponentReview.js +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaCorrect.js +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaGroup.js +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaGroupReview.js +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaSchema.js +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaSchemaReview.js +1 -1
- package/lib/orchestrate/prisma/programmers/AutoBeDatabaseAuthorizationProgrammer.js +23 -23
- package/lib/orchestrate/prisma/programmers/AutoBeDatabaseAuthorizationReviewProgrammer.js +7 -7
- package/lib/orchestrate/prisma/programmers/AutoBeDatabaseComponentProgrammer.js +5 -5
- package/lib/orchestrate/prisma/programmers/AutoBeDatabaseComponentReviewProgrammer.js +20 -20
- package/lib/orchestrate/prisma/programmers/AutoBeDatabaseGroupProgrammer.js +13 -13
- package/lib/orchestrate/prisma/programmers/AutoBeDatabaseGroupReviewProgrammer.js +51 -51
- package/lib/orchestrate/prisma/programmers/AutoBeDatabaseSchemaProgrammer.js +25 -25
- package/lib/orchestrate/realize/histories/transformRealizeAuthorizationCorrectHistory.js +28 -28
- package/lib/orchestrate/realize/histories/transformRealizeAuthorizationWriteHistory.js +14 -14
- package/lib/orchestrate/realize/histories/transformRealizeCollectorCorrectHistory.js +42 -42
- package/lib/orchestrate/realize/histories/transformRealizeCollectorPlanHistory.js +27 -27
- package/lib/orchestrate/realize/histories/transformRealizeCollectorWriteHistory.js +57 -57
- package/lib/orchestrate/realize/histories/transformRealizeCorrectCastingHistory.js +35 -35
- package/lib/orchestrate/realize/histories/transformRealizeOperationCorrectHistory.js +14 -14
- package/lib/orchestrate/realize/histories/transformRealizeOperationWriteHistory.js +37 -37
- package/lib/orchestrate/realize/histories/transformRealizeOperationWriteHistory.js.map +1 -1
- package/lib/orchestrate/realize/histories/transformRealizeTransformerCorrectHistory.js +47 -47
- package/lib/orchestrate/realize/histories/transformRealizeTransformerPlanHistory.js +27 -27
- package/lib/orchestrate/realize/histories/transformRealizeTransformerWriteHistory.js +51 -51
- package/lib/orchestrate/realize/orchestrateRealizeAuthorizationCorrect.js +1 -1
- package/lib/orchestrate/realize/orchestrateRealizeAuthorizationWrite.js +1 -1
- package/lib/orchestrate/realize/orchestrateRealizeCollectorCorrectOverall.js +1 -1
- package/lib/orchestrate/realize/orchestrateRealizeCollectorPlan.js +11 -11
- package/lib/orchestrate/realize/orchestrateRealizeCollectorWrite.js +1 -1
- package/lib/orchestrate/realize/orchestrateRealizeOperationCorrectOverall.js +1 -1
- package/lib/orchestrate/realize/orchestrateRealizeOperationWrite.js +1 -1
- package/lib/orchestrate/realize/orchestrateRealizeTransformerCorrectOverall.js +1 -1
- package/lib/orchestrate/realize/orchestrateRealizeTransformerPlan.js +11 -11
- package/lib/orchestrate/realize/orchestrateRealizeTransformerWrite.js +1 -1
- package/lib/orchestrate/realize/programmers/AutoBeRealizeCollectorProgrammer.js +41 -41
- package/lib/orchestrate/realize/programmers/AutoBeRealizeOperationProgrammer.js +21 -21
- package/lib/orchestrate/realize/programmers/AutoBeRealizeTransformerProgrammer.js +57 -57
- package/lib/orchestrate/realize/utils/getRealizeWriteInputType.js +3 -3
- package/lib/orchestrate/realize/utils/printErrorHints.js +5 -5
- package/lib/orchestrate/test/compile/getTestImportStatements.js +9 -9
- package/lib/orchestrate/test/histories/transformTestAuthorizeWriteHistory.js +38 -38
- package/lib/orchestrate/test/histories/transformTestGenerationWriteHistory.js +79 -79
- package/lib/orchestrate/test/histories/transformTestOperationWriteHistory.js +162 -162
- package/lib/orchestrate/test/histories/transformTestPrepareWriteHistory.js +54 -54
- package/lib/orchestrate/test/histories/transformTestScenarioHistory.js +31 -31
- package/lib/orchestrate/test/histories/transformTestScenarioReviewHistory.js +27 -27
- package/lib/orchestrate/test/orchestrateTestScenario.js +1 -1
- package/lib/orchestrate/test/orchestrateTestScenarioReview.js +1 -1
- package/lib/orchestrate/test/programmers/AutoBeTestAuthorizeProgrammer.js +31 -31
- package/lib/orchestrate/test/programmers/AutoBeTestGenerateProgrammer.js +23 -23
- package/lib/orchestrate/test/programmers/AutoBeTestOperationProgrammer.js +6 -6
- package/lib/orchestrate/test/programmers/AutoBeTestPrepareProgrammer.js +34 -34
- package/lib/orchestrate/test/programmers/AutoBeTestScenarioProgrammer.js +39 -39
- package/lib/utils/predicateStateMessage.js +19 -19
- package/lib/utils/validateEmptyCode.js +16 -16
- package/package.json +5 -5
- package/src/AutoBeAgent.ts +374 -374
- package/src/AutoBeAgentBase.ts +126 -126
- package/src/AutoBeMockAgent.ts +254 -254
- package/src/constants/AutoBeConfigConstant.ts +173 -173
- package/src/constants/AutoBeTemplateFileConstant.ts +1 -1
- package/src/context/AutoBeContext.ts +107 -107
- package/src/context/AutoBeState.ts +66 -66
- package/src/context/AutoBeTokenUsage.ts +307 -307
- package/src/context/AutoBeTokenUsageComponent.ts +227 -227
- package/src/describe/describe.ts +47 -47
- package/src/describe/image/histories/transformImageDescribeDraftHistories.ts +16 -16
- package/src/describe/image/orchestrateImageDescribeDraft.ts +200 -200
- package/src/describe/image/structures/IAutoBeImageDescribeDraftApplication.ts +92 -92
- package/src/describe/imageDescribe.ts +64 -64
- package/src/factory/consentFunctionCall.ts +141 -141
- package/src/factory/createAgenticaHistory.ts +71 -71
- package/src/factory/createAutoBeContext.ts +584 -584
- package/src/factory/createAutoBeMessageContent.ts +36 -36
- package/src/factory/createAutoBeState.ts +20 -20
- package/src/factory/getAutoBeGenerated.ts +317 -317
- package/src/factory/getAutoBeRealizeGenerated.ts +31 -31
- package/src/factory/getCriticalCompiler.ts +52 -52
- package/src/factory/index.ts +1 -1
- package/src/factory/mergeSystemMessages.ts +60 -60
- package/src/factory/supportFunctionCallFallback.ts +214 -214
- package/src/factory/supportMistral.ts +138 -138
- package/src/index.ts +16 -16
- package/src/orchestrate/analyze/fillTocDeterministic.ts +280 -280
- package/src/orchestrate/analyze/histories/transformAnalyzeScenarioHistory.ts +55 -55
- package/src/orchestrate/analyze/histories/transformAnalyzeScenarioReviewHistory.ts +74 -74
- package/src/orchestrate/analyze/histories/transformAnalyzeSectionCrossFileReviewHistory.ts +179 -179
- package/src/orchestrate/analyze/histories/transformAnalyzeSectionReviewHistory.ts +163 -163
- package/src/orchestrate/analyze/histories/transformAnalyzeWriteSectionHistory.ts +191 -191
- package/src/orchestrate/analyze/histories/transformAnalyzeWriteSectionPatchHistory.ts +122 -122
- package/src/orchestrate/analyze/histories/transformAnalyzeWriteUnitHistory.ts +161 -161
- package/src/orchestrate/analyze/index.ts +7 -7
- package/src/orchestrate/analyze/orchestrateAnalyze.ts +1693 -1693
- package/src/orchestrate/analyze/orchestrateAnalyzeScenario.ts +267 -267
- package/src/orchestrate/analyze/orchestrateAnalyzeScenarioReview.ts +122 -122
- package/src/orchestrate/analyze/orchestrateAnalyzeSectionCrossFileReview.ts +146 -146
- package/src/orchestrate/analyze/orchestrateAnalyzeSectionReview.ts +154 -154
- package/src/orchestrate/analyze/orchestrateAnalyzeWriteSection.ts +388 -388
- package/src/orchestrate/analyze/orchestrateAnalyzeWriteSectionPatch.ts +407 -407
- package/src/orchestrate/analyze/orchestrateAnalyzeWriteUnit.ts +348 -348
- package/src/orchestrate/analyze/programmers/AutoBeAnalyzeProgrammer.ts +149 -149
- package/src/orchestrate/analyze/structures/FixedAnalyzeTemplate.ts +961 -961
- package/src/orchestrate/analyze/structures/IAutoBeAnalyzeScenarioApplication.ts +141 -141
- package/src/orchestrate/analyze/structures/IAutoBeAnalyzeScenarioReviewApplication.ts +96 -96
- package/src/orchestrate/analyze/structures/IAutoBeAnalyzeSectionCrossFileReviewApplication.ts +160 -160
- package/src/orchestrate/analyze/structures/IAutoBeAnalyzeSectionReviewApplication.ts +192 -192
- package/src/orchestrate/analyze/structures/IAutoBeAnalyzeWriteSectionApplication.ts +142 -142
- package/src/orchestrate/analyze/structures/IAutoBeAnalyzeWriteUnitApplication.ts +123 -123
- package/src/orchestrate/analyze/utils/buildConstraintConsistencyReport.ts +813 -813
- package/src/orchestrate/analyze/utils/buildErrorCodeRegistry.ts +324 -324
- package/src/orchestrate/analyze/utils/buildHardValidators.ts +88 -88
- package/src/orchestrate/analyze/utils/detectInventedEntities.ts +87 -87
- package/src/orchestrate/analyze/utils/detectProseConstraintConflicts.ts +319 -319
- package/src/orchestrate/analyze/utils/repairSectionReviewUtils.ts +181 -181
- package/src/orchestrate/analyze/utils/repairUtils.ts +60 -60
- package/src/orchestrate/analyze/utils/validateScenarioBasics.ts +104 -104
- package/src/orchestrate/common/AutoBePreliminaryController.ts +400 -400
- package/src/orchestrate/common/histories/transformCommonCorrectCastingHistory.ts +32 -32
- package/src/orchestrate/common/histories/transformPreliminaryHistory.ts +742 -742
- package/src/orchestrate/common/histories/transformPreviousAndLatestCorrectHistory.ts +77 -77
- package/src/orchestrate/common/internal/complementPreliminaryCollection.ts +263 -263
- package/src/orchestrate/common/internal/convertToSectionEntries.ts +57 -57
- package/src/orchestrate/common/internal/createPreliminaryCollection.ts +76 -76
- package/src/orchestrate/common/internal/fixPrelminaryApplication.ts +346 -346
- package/src/orchestrate/common/internal/validatePreliminary.ts +671 -671
- package/src/orchestrate/common/orchestrateCommonCorrectCasting.ts +223 -223
- package/src/orchestrate/common/orchestratePreliminary.ts +610 -610
- package/src/orchestrate/common/structures/AutoBePreliminaryRequest.ts +42 -42
- package/src/orchestrate/common/structures/IAnalysisSectionEntry.ts +35 -35
- package/src/orchestrate/common/structures/IAutoBeCommonCorrectCastingApplication.ts +72 -72
- package/src/orchestrate/common/structures/IAutoBeOrchestrateResult.ts +28 -28
- package/src/orchestrate/common/structures/IAutoBePreliminaryCollection.ts +52 -52
- package/src/orchestrate/common/structures/IAutoBePreliminaryGetAnalysisSections.ts +34 -34
- package/src/orchestrate/common/structures/IAutoBePreliminaryGetDatabaseSchemas.ts +31 -31
- package/src/orchestrate/common/structures/IAutoBePreliminaryGetInterfaceOperations.ts +32 -32
- package/src/orchestrate/common/structures/IAutoBePreliminaryGetInterfaceSchemas.ts +31 -31
- package/src/orchestrate/common/structures/IAutoBePreliminaryGetPreviousAnalysisSections.ts +28 -28
- package/src/orchestrate/common/structures/IAutoBePreliminaryGetPreviousDatabaseSchemas.ts +88 -88
- package/src/orchestrate/common/structures/IAutoBePreliminaryGetPreviousInterfaceOperations.ts +102 -102
- package/src/orchestrate/common/structures/IAutoBePreliminaryGetPreviousInterfaceSchemas.ts +105 -105
- package/src/orchestrate/common/structures/IAutoBePreliminaryGetRealizeCollectors.ts +32 -32
- package/src/orchestrate/common/structures/IAutoBePreliminaryGetRealizeTransformers.ts +32 -32
- package/src/orchestrate/facade/createAutoBeFacadeController.ts +118 -118
- package/src/orchestrate/facade/histories/IAutoBeFacadeApplication.ts +139 -139
- package/src/orchestrate/facade/histories/IAutoBeFacadeApplicationProps.ts +8 -8
- package/src/orchestrate/facade/histories/IAutoBeFacadeApplicationResult.ts +9 -9
- package/src/orchestrate/facade/structures/transformFacadeStateMessage.ts +59 -59
- package/src/orchestrate/index.ts +5 -5
- package/src/orchestrate/interface/histories/transformInterfaceActionEndpointReviewHistory.ts +83 -83
- package/src/orchestrate/interface/histories/transformInterfaceActionEndpointWriteHistory.ts +78 -78
- package/src/orchestrate/interface/histories/transformInterfaceAuthorizationHistory.ts +129 -129
- package/src/orchestrate/interface/histories/transformInterfaceBaseEndpointReviewHistory.ts +74 -74
- package/src/orchestrate/interface/histories/transformInterfaceBaseEndpointWriteHistory.ts +68 -68
- package/src/orchestrate/interface/histories/transformInterfaceCommonHistory.ts +64 -64
- package/src/orchestrate/interface/histories/transformInterfaceEndpointAuthorizationSection.ts +42 -42
- package/src/orchestrate/interface/histories/transformInterfaceGroupHistory.ts +103 -103
- package/src/orchestrate/interface/histories/transformInterfaceOperationHistory.ts +81 -81
- package/src/orchestrate/interface/histories/transformInterfaceOperationParameterHistory.ts +53 -53
- package/src/orchestrate/interface/histories/transformInterfaceOperationReviewHistory.ts +49 -49
- package/src/orchestrate/interface/histories/transformInterfacePrerequisiteHistory.ts +94 -94
- package/src/orchestrate/interface/histories/transformInterfaceSchemaCastingHistory.ts +122 -122
- package/src/orchestrate/interface/histories/transformInterfaceSchemaComplementHistory.ts +192 -192
- package/src/orchestrate/interface/histories/transformInterfaceSchemaRefineHistory.ts +189 -189
- package/src/orchestrate/interface/histories/transformInterfaceSchemaRenameHistory.ts +63 -63
- package/src/orchestrate/interface/histories/transformInterfaceSchemaReviewHistory.ts +173 -173
- package/src/orchestrate/interface/histories/transformInterfaceSchemaWriteHistory.ts +88 -88
- package/src/orchestrate/interface/index.ts +6 -6
- package/src/orchestrate/interface/orchestrateInterface.ts +118 -118
- package/src/orchestrate/interface/orchestrateInterfaceActionEndpoint.ts +58 -58
- package/src/orchestrate/interface/orchestrateInterfaceAuthorization.ts +208 -208
- package/src/orchestrate/interface/orchestrateInterfaceBaseEndpoint.ts +55 -55
- package/src/orchestrate/interface/orchestrateInterfaceEndpoint.ts +67 -67
- package/src/orchestrate/interface/orchestrateInterfaceEndpointOverall.ts +80 -80
- package/src/orchestrate/interface/orchestrateInterfaceEndpointReview.ts +212 -212
- package/src/orchestrate/interface/orchestrateInterfaceEndpointWrite.ts +236 -236
- package/src/orchestrate/interface/orchestrateInterfaceGroup.ts +166 -166
- package/src/orchestrate/interface/orchestrateInterfaceOperation.ts +322 -322
- package/src/orchestrate/interface/orchestrateInterfaceOperationReview.ts +245 -245
- package/src/orchestrate/interface/orchestrateInterfacePrerequisite.ts +240 -240
- package/src/orchestrate/interface/orchestrateInterfaceSchema.ts +191 -191
- package/src/orchestrate/interface/orchestrateInterfaceSchemaCasting.ts +274 -274
- package/src/orchestrate/interface/orchestrateInterfaceSchemaComplement.ts +329 -329
- package/src/orchestrate/interface/orchestrateInterfaceSchemaRefine.ts +292 -292
- package/src/orchestrate/interface/orchestrateInterfaceSchemaRename.ts +266 -266
- package/src/orchestrate/interface/orchestrateInterfaceSchemaReview.ts +310 -310
- package/src/orchestrate/interface/orchestrateInterfaceSchemaWrite.ts +283 -283
- package/src/orchestrate/interface/programmers/AutoBeInterfaceAuthorizationProgrammer.ts +260 -260
- package/src/orchestrate/interface/programmers/AutoBeInterfaceEndpointProgrammer.ts +155 -155
- package/src/orchestrate/interface/programmers/AutoBeInterfaceEndpointReviewProgrammer.ts +139 -139
- package/src/orchestrate/interface/programmers/AutoBeInterfaceOperationProgrammer.ts +277 -277
- package/src/orchestrate/interface/programmers/AutoBeInterfacePrerequisiteProgrammer.ts +259 -259
- package/src/orchestrate/interface/programmers/AutoBeInterfaceSchemaProgrammer.ts +152 -152
- package/src/orchestrate/interface/programmers/AutoBeInterfaceSchemaPropertyReviseProgrammer.ts +347 -347
- package/src/orchestrate/interface/programmers/AutoBeInterfaceSchemaRefineProgrammer.ts +183 -183
- package/src/orchestrate/interface/programmers/AutoBeInterfaceSchemaReviewProgrammer.ts +263 -263
- package/src/orchestrate/interface/structures/IAutoBeInterfaceAuthorizationApplication.ts +135 -135
- package/src/orchestrate/interface/structures/IAutoBeInterfaceEndpointReviewApplication.ts +128 -128
- package/src/orchestrate/interface/structures/IAutoBeInterfaceEndpointWriteApplication.ts +133 -133
- package/src/orchestrate/interface/structures/IAutoBeInterfaceGroupApplication.ts +122 -122
- package/src/orchestrate/interface/structures/IAutoBeInterfaceOperationApplication.ts +178 -178
- package/src/orchestrate/interface/structures/IAutoBeInterfaceOperationReviewApplication.ts +175 -175
- package/src/orchestrate/interface/structures/IAutoBeInterfacePrerequisiteApplication.ts +130 -130
- package/src/orchestrate/interface/structures/IAutoBeInterfaceSchemaApplication.ts +121 -121
- package/src/orchestrate/interface/structures/IAutoBeInterfaceSchemaCastingApplication.ts +153 -153
- package/src/orchestrate/interface/structures/IAutoBeInterfaceSchemaComplementApplication.ts +123 -123
- package/src/orchestrate/interface/structures/IAutoBeInterfaceSchemaRefineApplication.ts +181 -181
- package/src/orchestrate/interface/structures/IAutoBeInterfaceSchemaRenameApplication.ts +45 -45
- package/src/orchestrate/interface/structures/IAutoBeInterfaceSchemaReviewApplication.ts +108 -108
- package/src/orchestrate/interface/utils/AutoBeJsonSchemaCollection.ts +42 -42
- package/src/orchestrate/interface/utils/AutoBeJsonSchemaFactory.ts +714 -714
- package/src/orchestrate/interface/utils/AutoBeJsonSchemaNamingConvention.ts +86 -86
- package/src/orchestrate/interface/utils/AutoBeJsonSchemaValidator.ts +725 -725
- package/src/orchestrate/interface/utils/fulfillJsonSchemaErrorMessages.ts +219 -219
- package/src/orchestrate/prisma/histories/transformPrismaAuthorizationHistory.ts +144 -144
- package/src/orchestrate/prisma/histories/transformPrismaAuthorizationReviewHistory.ts +104 -104
- package/src/orchestrate/prisma/histories/transformPrismaComponentReviewHistory.ts +97 -97
- package/src/orchestrate/prisma/histories/transformPrismaComponentsHistory.ts +136 -136
- package/src/orchestrate/prisma/histories/transformPrismaCorrectHistory.ts +41 -41
- package/src/orchestrate/prisma/histories/transformPrismaGroupHistory.ts +63 -63
- package/src/orchestrate/prisma/histories/transformPrismaGroupReviewHistory.ts +79 -79
- package/src/orchestrate/prisma/histories/transformPrismaSchemaHistory.ts +97 -97
- package/src/orchestrate/prisma/histories/transformPrismaSchemaReviewHistory.ts +126 -126
- package/src/orchestrate/prisma/index.ts +7 -7
- package/src/orchestrate/prisma/orchestratePrisma.ts +296 -296
- package/src/orchestrate/prisma/orchestratePrismaAuthorization.ts +173 -173
- package/src/orchestrate/prisma/orchestratePrismaAuthorizationReview.ts +183 -183
- package/src/orchestrate/prisma/orchestratePrismaComponent.ts +205 -205
- package/src/orchestrate/prisma/orchestratePrismaComponentReview.ts +205 -205
- package/src/orchestrate/prisma/orchestratePrismaCorrect.ts +265 -265
- package/src/orchestrate/prisma/orchestratePrismaGroup.ts +121 -121
- package/src/orchestrate/prisma/orchestratePrismaGroupReview.ts +141 -141
- package/src/orchestrate/prisma/orchestratePrismaSchema.ts +218 -218
- package/src/orchestrate/prisma/orchestratePrismaSchemaReview.ts +220 -220
- package/src/orchestrate/prisma/programmers/AutoBeDatabaseAuthorizationProgrammer.ts +86 -86
- package/src/orchestrate/prisma/programmers/AutoBeDatabaseAuthorizationReviewProgrammer.ts +103 -103
- package/src/orchestrate/prisma/programmers/AutoBeDatabaseComponentProgrammer.ts +80 -80
- package/src/orchestrate/prisma/programmers/AutoBeDatabaseComponentReviewProgrammer.ts +168 -168
- package/src/orchestrate/prisma/programmers/AutoBeDatabaseGroupProgrammer.ts +63 -63
- package/src/orchestrate/prisma/programmers/AutoBeDatabaseGroupReviewProgrammer.ts +210 -210
- package/src/orchestrate/prisma/programmers/AutoBeDatabaseModelProgrammer.ts +57 -57
- package/src/orchestrate/prisma/programmers/AutoBeDatabaseSchemaProgrammer.ts +92 -92
- package/src/orchestrate/prisma/structures/IAutoBeDatabaseAuthorizationApplication.ts +147 -147
- package/src/orchestrate/prisma/structures/IAutoBeDatabaseAuthorizationReviewApplication.ts +153 -153
- package/src/orchestrate/prisma/structures/IAutoBeDatabaseComponentApplication.ts +142 -142
- package/src/orchestrate/prisma/structures/IAutoBeDatabaseComponentReviewApplication.ts +151 -151
- package/src/orchestrate/prisma/structures/IAutoBeDatabaseCorrectApplication.ts +157 -157
- package/src/orchestrate/prisma/structures/IAutoBeDatabaseGroupApplication.ts +117 -117
- package/src/orchestrate/prisma/structures/IAutoBeDatabaseGroupReviewApplication.ts +154 -154
- package/src/orchestrate/prisma/structures/IAutoBeDatabaseSchemaApplication.ts +144 -144
- package/src/orchestrate/prisma/structures/IAutoBeDatabaseSchemaReviewApplication.ts +138 -138
- package/src/orchestrate/realize/histories/transformRealizeAuthorizationCorrectHistory.ts +89 -89
- package/src/orchestrate/realize/histories/transformRealizeAuthorizationWriteHistory.ts +45 -45
- package/src/orchestrate/realize/histories/transformRealizeCollectorCorrectHistory.ts +137 -137
- package/src/orchestrate/realize/histories/transformRealizeCollectorPlanHistory.ts +64 -64
- package/src/orchestrate/realize/histories/transformRealizeCollectorWriteHistory.ts +147 -147
- package/src/orchestrate/realize/histories/transformRealizeCorrectCastingHistory.ts +69 -69
- package/src/orchestrate/realize/histories/transformRealizeOperationCorrectHistory.ts +94 -94
- package/src/orchestrate/realize/histories/transformRealizeOperationWriteHistory.ts +127 -127
- package/src/orchestrate/realize/histories/transformRealizeTransformerCorrectHistory.ts +147 -147
- package/src/orchestrate/realize/histories/transformRealizeTransformerPlanHistory.ts +61 -61
- package/src/orchestrate/realize/histories/transformRealizeTransformerWriteHistory.ts +133 -133
- package/src/orchestrate/realize/histories/transformRealizeWriteMembershipHistory.ts +30 -30
- package/src/orchestrate/realize/index.ts +3 -3
- package/src/orchestrate/realize/internal/orchestrateRealizeCorrectCasting.ts +444 -444
- package/src/orchestrate/realize/internal/orchestrateRealizeCorrectOverall.ts +449 -449
- package/src/orchestrate/realize/orchestrateRealize.ts +143 -143
- package/src/orchestrate/realize/orchestrateRealizeAuthorizationCorrect.ts +207 -207
- package/src/orchestrate/realize/orchestrateRealizeAuthorizationWrite.ts +209 -209
- package/src/orchestrate/realize/orchestrateRealizeCollector.ts +41 -41
- package/src/orchestrate/realize/orchestrateRealizeCollectorCorrectCasting.ts +43 -43
- package/src/orchestrate/realize/orchestrateRealizeCollectorCorrectOverall.ts +157 -157
- package/src/orchestrate/realize/orchestrateRealizeCollectorPlan.ts +264 -264
- package/src/orchestrate/realize/orchestrateRealizeCollectorWrite.ts +225 -225
- package/src/orchestrate/realize/orchestrateRealizeOperation.ts +48 -48
- package/src/orchestrate/realize/orchestrateRealizeOperationCorrectCasting.ts +69 -69
- package/src/orchestrate/realize/orchestrateRealizeOperationCorrectOverall.ts +173 -173
- package/src/orchestrate/realize/orchestrateRealizeOperationWrite.ts +262 -262
- package/src/orchestrate/realize/orchestrateRealizeTransformer.ts +41 -41
- package/src/orchestrate/realize/orchestrateRealizeTransformerCorrectCasting.ts +38 -38
- package/src/orchestrate/realize/orchestrateRealizeTransformerCorrectOverall.ts +160 -160
- package/src/orchestrate/realize/orchestrateRealizeTransformerPlan.ts +254 -254
- package/src/orchestrate/realize/orchestrateRealizeTransformerWrite.ts +226 -226
- package/src/orchestrate/realize/programmers/AutoBeRealizeCollectorProgrammer.ts +424 -424
- package/src/orchestrate/realize/programmers/AutoBeRealizeOperationProgrammer.ts +409 -409
- package/src/orchestrate/realize/programmers/AutoBeRealizeTransformerProgrammer.ts +451 -451
- package/src/orchestrate/realize/programmers/compileRealizeFiles.ts +65 -65
- package/src/orchestrate/realize/structures/IAutoBeRealizeAuthorizationCorrectApplication.ts +119 -119
- package/src/orchestrate/realize/structures/IAutoBeRealizeAuthorizationWriteApplication.ts +167 -167
- package/src/orchestrate/realize/structures/IAutoBeRealizeCollectorCorrectApplication.ts +191 -191
- package/src/orchestrate/realize/structures/IAutoBeRealizeCollectorPlanApplication.ts +177 -177
- package/src/orchestrate/realize/structures/IAutoBeRealizeCollectorWriteApplication.ts +207 -207
- package/src/orchestrate/realize/structures/IAutoBeRealizeFunctionFailure.ts +11 -11
- package/src/orchestrate/realize/structures/IAutoBeRealizeOperationCorrectApplication.ts +134 -134
- package/src/orchestrate/realize/structures/IAutoBeRealizeOperationWriteApplication.ts +138 -138
- package/src/orchestrate/realize/structures/IAutoBeRealizeScenarioResult.ts +32 -32
- package/src/orchestrate/realize/structures/IAutoBeRealizeTransformerCorrectApplication.ts +248 -248
- package/src/orchestrate/realize/structures/IAutoBeRealizeTransformerPlanApplication.ts +150 -150
- package/src/orchestrate/realize/structures/IAutoBeRealizeTransformerWriteApplication.ts +278 -278
- package/src/orchestrate/realize/utils/AuthorizationFileSystem.ts +10 -10
- package/src/orchestrate/realize/utils/AutoBeRealizeAuthorizationFileSystem.ts +9 -9
- package/src/orchestrate/realize/utils/AutoBeRealizeAuthorizationReplaceImport.ts +62 -62
- package/src/orchestrate/realize/utils/InternalFileSystem.ts +12 -12
- package/src/orchestrate/realize/utils/ProviderFileSystem.ts +4 -4
- package/src/orchestrate/realize/utils/filterDiagnostics.ts +25 -25
- package/src/orchestrate/realize/utils/generateTS2339Hints.ts +54 -54
- package/src/orchestrate/realize/utils/getRealizeWriteImportStatements.ts +42 -42
- package/src/orchestrate/realize/utils/getRealizeWriteInputType.ts +88 -88
- package/src/orchestrate/realize/utils/printErrorHints.ts +54 -54
- package/src/orchestrate/test/compile/getTestArtifacts.ts +124 -124
- package/src/orchestrate/test/compile/getTestExternalDeclarations.ts +39 -39
- package/src/orchestrate/test/compile/getTestImportStatements.ts +27 -27
- package/src/orchestrate/test/experimental/orchestrateTestCorrect.ast +237 -237
- package/src/orchestrate/test/experimental/orchestrateTestWrite.ast +322 -322
- package/src/orchestrate/test/experimental/transformTestCorrectHistories.ast +52 -52
- package/src/orchestrate/test/histories/transformTestAuthorizeWriteHistory.ts +80 -80
- package/src/orchestrate/test/histories/transformTestCorrectOverallHistory.ts +116 -116
- package/src/orchestrate/test/histories/transformTestGenerationWriteHistory.ts +118 -118
- package/src/orchestrate/test/histories/transformTestOperationWriteHistory.ts +287 -287
- package/src/orchestrate/test/histories/transformTestPrepareWriteHistory.ts +95 -95
- package/src/orchestrate/test/histories/transformTestScenarioHistory.ts +120 -120
- package/src/orchestrate/test/histories/transformTestScenarioReviewHistory.ts +99 -99
- package/src/orchestrate/test/histories/transformTestValidateEvent.ts +11 -11
- package/src/orchestrate/test/index.ts +5 -5
- package/src/orchestrate/test/internal/orchestrateTestCorrectCasting.ts +96 -96
- package/src/orchestrate/test/internal/orchestrateTestCorrectOverall.ts +219 -219
- package/src/orchestrate/test/internal/orchestrateTestCorrectRequest.ts +206 -206
- package/src/orchestrate/test/orchestrateTest.ts +161 -161
- package/src/orchestrate/test/orchestrateTestAuthorize.ts +125 -125
- package/src/orchestrate/test/orchestrateTestAuthorizeWrite.ts +263 -263
- package/src/orchestrate/test/orchestrateTestGenerate.ts +121 -121
- package/src/orchestrate/test/orchestrateTestGenerateWrite.ts +211 -211
- package/src/orchestrate/test/orchestrateTestOperation.ts +133 -133
- package/src/orchestrate/test/orchestrateTestOperationWrite.ts +221 -221
- package/src/orchestrate/test/orchestrateTestPrepare.ts +117 -117
- package/src/orchestrate/test/orchestrateTestPrepareWrite.ts +264 -264
- package/src/orchestrate/test/orchestrateTestScenario.ts +290 -290
- package/src/orchestrate/test/orchestrateTestScenarioReview.ts +262 -262
- package/src/orchestrate/test/programmers/AutoBeTestAuthorizeProgrammer.ts +149 -149
- package/src/orchestrate/test/programmers/AutoBeTestFunctionProgrammer.ts +90 -90
- package/src/orchestrate/test/programmers/AutoBeTestGenerateProgrammer.ts +170 -170
- package/src/orchestrate/test/programmers/AutoBeTestOperationProgrammer.ts +168 -168
- package/src/orchestrate/test/programmers/AutoBeTestPrepareProgrammer.ts +261 -261
- package/src/orchestrate/test/programmers/AutoBeTestScenarioProgrammer.ts +316 -316
- package/src/orchestrate/test/structures/IAutoBeTestArtifacts.ts +8 -8
- package/src/orchestrate/test/structures/IAutoBeTestAuthorizationWriteApplication.ts +113 -113
- package/src/orchestrate/test/structures/IAutoBeTestAuthorizeWriteResult.ts +10 -10
- package/src/orchestrate/test/structures/IAutoBeTestCorrectOverallApplication.ts +134 -134
- package/src/orchestrate/test/structures/IAutoBeTestCorrectRequestApplication.ts +152 -152
- package/src/orchestrate/test/structures/IAutoBeTestFunction.ts +10 -10
- package/src/orchestrate/test/structures/IAutoBeTestFunctionFailure.ts +10 -10
- package/src/orchestrate/test/structures/IAutoBeTestGenerateProcedure.ts +15 -15
- package/src/orchestrate/test/structures/IAutoBeTestGenerationWriteApplication.ts +145 -145
- package/src/orchestrate/test/structures/IAutoBeTestOperationProcedure.ts +17 -17
- package/src/orchestrate/test/structures/IAutoBeTestOperationWriteApplication.ts +162 -162
- package/src/orchestrate/test/structures/IAutoBeTestPrepareCorrectOverallApplication.ts +194 -194
- package/src/orchestrate/test/structures/IAutoBeTestPrepareProcedure.ts +8 -8
- package/src/orchestrate/test/structures/IAutoBeTestPrepareWriteApplication.ts +147 -147
- package/src/orchestrate/test/structures/IAutoBeTestProcedure.ts +10 -10
- package/src/orchestrate/test/structures/IAutoBeTestScenarioApplication.ts +105 -105
- package/src/orchestrate/test/structures/IAutoBeTestScenarioArtifacts.ts +8 -8
- package/src/orchestrate/test/structures/IAutoBeTestScenarioAuthorizationActor.ts +7 -7
- package/src/orchestrate/test/structures/IAutoBeTestScenarioReviewApplication.ts +133 -133
- package/src/orchestrate/test/utils/getPrerequisites.ts +51 -51
- package/src/orchestrate/test/utils/getReferenceIds.ts +26 -26
- package/src/orchestrate/test/utils/insertScriptToTestResult.ts +14 -14
- package/src/structures/IAutoBeConfig.ts +110 -110
- package/src/structures/IAutoBeOrchestrateHistory.ts +44 -44
- package/src/structures/IAutoBeProps.ts +102 -102
- package/src/structures/IAutoBeVendor.ts +113 -113
- package/src/utils/AutoBePreliminaryExhaustedError.ts +30 -30
- package/src/utils/AutoBeTimeoutError.ts +35 -35
- package/src/utils/EmbeddingProvider.ts +4 -4
- package/src/utils/LocalEmbeddingProvider.ts +145 -145
- package/src/utils/RAGRetrieval.ts +411 -411
- package/src/utils/TimedConversation.ts +125 -125
- package/src/utils/backoffRetry.ts +169 -169
- package/src/utils/divideArray.ts +35 -35
- package/src/utils/emplaceMap.ts +31 -31
- package/src/utils/executeCachedBatch.ts +67 -67
- package/src/utils/forceRetry.ts +15 -15
- package/src/utils/getEmbedder.ts +16 -16
- package/src/utils/parseTextFunctionCall.ts +437 -437
- package/src/utils/predicateStateMessage.ts +131 -131
- package/src/utils/validateEmptyCode.ts +73 -73
- package/src/utils/validateEnglishOnly.ts +224 -224
- package/README.md +0 -261
|
@@ -1,725 +1,725 @@
|
|
|
1
|
-
import { AutoBeOpenApi } from "@autobe/interface";
|
|
2
|
-
import { AutoBeOpenApiTypeChecker, StringUtil } from "@autobe/utils";
|
|
3
|
-
import { NamingConvention } from "@typia/utils";
|
|
4
|
-
import { IValidation } from "typia";
|
|
5
|
-
|
|
6
|
-
import { AutoBeJsonSchemaFactory } from "./AutoBeJsonSchemaFactory";
|
|
7
|
-
|
|
8
|
-
export namespace AutoBeJsonSchemaValidator {
|
|
9
|
-
export const isObjectType = (props: {
|
|
10
|
-
operations: AutoBeOpenApi.IOperation[];
|
|
11
|
-
typeName: string;
|
|
12
|
-
}): boolean =>
|
|
13
|
-
props.typeName.endsWith(".IAuthorized") ||
|
|
14
|
-
props.typeName.endsWith(".IRequest") ||
|
|
15
|
-
props.typeName.endsWith(".ISummary") ||
|
|
16
|
-
props.typeName.endsWith(".IInvert") ||
|
|
17
|
-
props.typeName.endsWith(".ICreate") ||
|
|
18
|
-
props.typeName.endsWith(".IUpdate") ||
|
|
19
|
-
props.typeName.endsWith(".IJoin") ||
|
|
20
|
-
props.typeName.endsWith(".ILogin") ||
|
|
21
|
-
props.operations.some(
|
|
22
|
-
(op) =>
|
|
23
|
-
op.requestBody?.typeName === props.typeName ||
|
|
24
|
-
op.responseBody?.typeName === props.typeName,
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
export const isPage = (key: string): boolean =>
|
|
28
|
-
key.startsWith("IPage") === true &&
|
|
29
|
-
key.startsWith("IPage.") === false &&
|
|
30
|
-
key !== "IPage";
|
|
31
|
-
|
|
32
|
-
export const isPreset = (typeName: string): boolean =>
|
|
33
|
-
AutoBeJsonSchemaFactory.DEFAULT_SCHEMAS[typeName] !== undefined ||
|
|
34
|
-
AutoBeJsonSchemaValidator.isPage(typeName) === true;
|
|
35
|
-
|
|
36
|
-
export interface IProps {
|
|
37
|
-
errors: IValidation.IError[];
|
|
38
|
-
operations: AutoBeOpenApi.IOperation[];
|
|
39
|
-
typeName: string;
|
|
40
|
-
schema: AutoBeOpenApi.IJsonSchema;
|
|
41
|
-
path: string;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export const validateSchema = (props: IProps): void => {
|
|
45
|
-
const vo = validateObjectType({
|
|
46
|
-
errors: props.errors,
|
|
47
|
-
operations: props.operations,
|
|
48
|
-
path: props.path,
|
|
49
|
-
});
|
|
50
|
-
validateAuthorization(props);
|
|
51
|
-
validateRecursive(props);
|
|
52
|
-
validateReferenceId(props);
|
|
53
|
-
validatePropertyNames(props);
|
|
54
|
-
validateNumericRanges(props);
|
|
55
|
-
|
|
56
|
-
vo(props.typeName, props.schema);
|
|
57
|
-
AutoBeOpenApiTypeChecker.skim({
|
|
58
|
-
schema: props.schema,
|
|
59
|
-
closure: (next, accessor) => {
|
|
60
|
-
if (AutoBeOpenApiTypeChecker.isReference(next) === false) return;
|
|
61
|
-
const key: string = next.$ref.split("/").pop()!;
|
|
62
|
-
validateKey({
|
|
63
|
-
errors: props.errors,
|
|
64
|
-
path: `${accessor}.$ref`,
|
|
65
|
-
key,
|
|
66
|
-
transform: (typeName) => `#/components/schemas/${typeName}`,
|
|
67
|
-
});
|
|
68
|
-
},
|
|
69
|
-
accessor: props.path,
|
|
70
|
-
});
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
export const validateKey = (props: {
|
|
74
|
-
errors: IValidation.IError[];
|
|
75
|
-
key: string;
|
|
76
|
-
path: string;
|
|
77
|
-
transform?: (typeName: string) => string;
|
|
78
|
-
}): void => {
|
|
79
|
-
const transform = props.transform ?? ((typeName: string) => typeName);
|
|
80
|
-
const elements: string[] = props.key.split(".");
|
|
81
|
-
if (elements.length > 2)
|
|
82
|
-
props.errors.push({
|
|
83
|
-
path: props.path,
|
|
84
|
-
expected: "At most one dot(.) character allowed in type name",
|
|
85
|
-
value: transform(props.key),
|
|
86
|
-
description: StringUtil.trim`
|
|
87
|
-
JSON schema type name allows at most one dot(.) character to separate
|
|
88
|
-
module name and interface name.
|
|
89
|
-
|
|
90
|
-
However, current key name ${transform(JSON.stringify(props.key))}
|
|
91
|
-
contains multiple dot(.) characters (${elements.length - 1} times).
|
|
92
|
-
|
|
93
|
-
Change it to a valid type name with at most one dot(.) character at the next time.
|
|
94
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
95
|
-
`,
|
|
96
|
-
});
|
|
97
|
-
if (elements.every(NamingConvention.variable) === false)
|
|
98
|
-
props.errors.push({
|
|
99
|
-
path: props.path,
|
|
100
|
-
expected: StringUtil.trim`
|
|
101
|
-
Valid variable name
|
|
102
|
-
|
|
103
|
-
${elements.map((s) => `- ${s}: ${NamingConvention.variable(s) ? "valid" : "invalid"}`).join("\n")}
|
|
104
|
-
`,
|
|
105
|
-
value: transform(props.key),
|
|
106
|
-
description: StringUtil.trim`
|
|
107
|
-
JSON schema type name must be a valid variable name.
|
|
108
|
-
|
|
109
|
-
Even though JSON schema type name allows dot(.) character, but
|
|
110
|
-
each segment separated by dot(.) must be a valid variable name.
|
|
111
|
-
|
|
112
|
-
Current key name ${transform(JSON.stringify(props.key))} is not valid.
|
|
113
|
-
Change it to a valid variable name at the next time.
|
|
114
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
115
|
-
`,
|
|
116
|
-
});
|
|
117
|
-
if (props.key.endsWith(".IPage")) {
|
|
118
|
-
const expected: string = `IPage${props.key.substring(0, props.key.length - 6)}`;
|
|
119
|
-
props.errors.push({
|
|
120
|
-
path: props.path,
|
|
121
|
-
expected: `"IPage" must be followed by another interface name. Use ${transform(JSON.stringify(expected))} instead.`,
|
|
122
|
-
value: transform(props.key),
|
|
123
|
-
description: StringUtil.trim`
|
|
124
|
-
"IPage" is a reserved type name for pagination response.
|
|
125
|
-
The pagination data type name must be post-fixed after "IPage".
|
|
126
|
-
|
|
127
|
-
However, you've defined ${transform(JSON.stringify(props.key))},
|
|
128
|
-
post-fixing ".IPage" after the pagination data type name.
|
|
129
|
-
|
|
130
|
-
Change it to a valid pagination type name to be
|
|
131
|
-
${transform(JSON.stringify(expected))} at the next time.
|
|
132
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
133
|
-
`,
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
if (props.key === "IPageIRequest")
|
|
137
|
-
props.errors.push({
|
|
138
|
-
path: props.path,
|
|
139
|
-
expected: `"IPageIRequest" is a mistake. Use "IPage.IRequest" instead.`,
|
|
140
|
-
value: transform(props.key),
|
|
141
|
-
description: StringUtil.trim`
|
|
142
|
-
You've taken a mistake that defines "${transform("IPageIRequest")}" as a type name.
|
|
143
|
-
However, as you've intended to define a pagination request type,
|
|
144
|
-
the correct type name is "${transform("IPage.IRequest")}" instead of "${transform("IPageIRequest")}".
|
|
145
|
-
|
|
146
|
-
Change it to "${transform("IPage.IRequest")}" at the next time.
|
|
147
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
148
|
-
`,
|
|
149
|
-
});
|
|
150
|
-
if (
|
|
151
|
-
props.key.startsWith("IPage") &&
|
|
152
|
-
props.key.startsWith("IPageI") === false &&
|
|
153
|
-
props.key !== "IPage.IPagination" &&
|
|
154
|
-
props.key !== "IPage.IRequest"
|
|
155
|
-
) {
|
|
156
|
-
const expected: string = `IPage${props.key
|
|
157
|
-
.substring(5)
|
|
158
|
-
.split(".")
|
|
159
|
-
.map((s) => (s.startsWith("I") ? s : `I${s}`))
|
|
160
|
-
.join(".")}`;
|
|
161
|
-
props.errors.push({
|
|
162
|
-
path: props.path,
|
|
163
|
-
expected: `Interface name starting with 'I' even after 'IPage': ${JSON.stringify(expected)}`,
|
|
164
|
-
value: transform(props.key),
|
|
165
|
-
description: StringUtil.trim`
|
|
166
|
-
JSON schema type name must be an interface name starting with 'I'.
|
|
167
|
-
Even though JSON schema type name allows dot(.) character, but
|
|
168
|
-
each segment separated by dot(.) must be an interface name starting
|
|
169
|
-
with 'I'.
|
|
170
|
-
|
|
171
|
-
Even in the case of pagination response, after 'IPage' prefix,
|
|
172
|
-
the remaining part must be an interface name starting with 'I'.
|
|
173
|
-
|
|
174
|
-
Current key name ${JSON.stringify(props.key)} is not valid. Change
|
|
175
|
-
it to a valid interface name to be ${JSON.stringify(expected)},
|
|
176
|
-
or change it to another valid interface name at the next time.
|
|
177
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
178
|
-
`,
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
if (elements.some((s) => s.startsWith("I") === false) === true) {
|
|
182
|
-
const expected: string = elements
|
|
183
|
-
.map((s) => (s.startsWith("I") ? s : `I${s}`))
|
|
184
|
-
.join(".");
|
|
185
|
-
props.errors.push({
|
|
186
|
-
path: props.path,
|
|
187
|
-
expected: `Interface name starting with 'I': ${JSON.stringify(expected)}`,
|
|
188
|
-
value: transform(props.key),
|
|
189
|
-
description: StringUtil.trim`
|
|
190
|
-
JSON schema type name must be an interface name starting with 'I'.
|
|
191
|
-
Even though JSON schema type name allows dot(.) character, but
|
|
192
|
-
each segment separated by dot(.) must be an interface name starting
|
|
193
|
-
with 'I'.
|
|
194
|
-
|
|
195
|
-
Current key name ${transform(JSON.stringify(props.key))} is not valid.
|
|
196
|
-
Change it to a valid interface name to be ${transform(JSON.stringify(expected))},
|
|
197
|
-
or change it to another valid interface name at the next time.
|
|
198
|
-
|
|
199
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
200
|
-
`,
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
if (
|
|
204
|
-
elements.length === 2 &&
|
|
205
|
-
(elements[1] === "IJoin" ||
|
|
206
|
-
elements[1] === "ILogin" ||
|
|
207
|
-
elements[1] === "IAuthorized" ||
|
|
208
|
-
elements[1] === "IRefresh") &&
|
|
209
|
-
elements[0].endsWith("Session") === true
|
|
210
|
-
)
|
|
211
|
-
props.errors.push({
|
|
212
|
-
path: props.path,
|
|
213
|
-
expected: JSON.stringify(
|
|
214
|
-
`${elements[0].replace("Session", "")}.${elements[1]}`,
|
|
215
|
-
),
|
|
216
|
-
value: transform(props.key),
|
|
217
|
-
description: StringUtil.trim`
|
|
218
|
-
You have attached ${elements[1]} to a Session type ${transform(JSON.stringify(props.key))},
|
|
219
|
-
but this is architecturally incorrect.
|
|
220
|
-
|
|
221
|
-
In production authentication systems, Actor and Session are separate concepts:
|
|
222
|
-
- **Actor** (e.g., User, Seller, Admin): The persistent user identity that performs
|
|
223
|
-
authentication actions - joining (registering), logging in, and receiving authorized tokens.
|
|
224
|
-
- **Session** (e.g., UserSession, SellerSession): The temporary authentication state that
|
|
225
|
-
tracks active login instances. Sessions are CREATED as a result of join/login operations,
|
|
226
|
-
but they do not perform these actions themselves.
|
|
227
|
-
|
|
228
|
-
Think about it semantically: An ACTOR joins the system and logs in. A SESSION is merely
|
|
229
|
-
a record that gets created when the actor authenticates. It makes no sense for a session
|
|
230
|
-
to "join" or "login" - only actors do that.
|
|
231
|
-
|
|
232
|
-
Therefore, authentication-related DTO types (IJoin, ILogin, IAuthorized, IRefresh) MUST
|
|
233
|
-
be attached to the Actor type, NEVER to the Session type.
|
|
234
|
-
|
|
235
|
-
Change ${transform(JSON.stringify(props.key))} to ${transform(JSON.stringify(`${elements[0].replace("Session", "")}.${elements[1]}`))} at the next time.
|
|
236
|
-
|
|
237
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
238
|
-
`,
|
|
239
|
-
});
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
const validateAuthorization = (props: IProps): void => {
|
|
243
|
-
if (props.typeName.endsWith(".IAuthorized") === true) {
|
|
244
|
-
if (AutoBeOpenApiTypeChecker.isObject(props.schema) === false) {
|
|
245
|
-
props.errors.push({
|
|
246
|
-
path: props.path,
|
|
247
|
-
expected: `AutoBeOpenApi.IJsonSchemaDescriptive<AutoBeOpenApi.IJsonSchema.IObject>`,
|
|
248
|
-
value: props.schema,
|
|
249
|
-
description: `${props.typeName} must be an object type for authorization responses. Note that, this is not a recommendation, but an instruction you must follow.`,
|
|
250
|
-
});
|
|
251
|
-
} else {
|
|
252
|
-
// Check if token property exists
|
|
253
|
-
props.schema.properties ??= {};
|
|
254
|
-
props.schema.properties["token"] = {
|
|
255
|
-
"x-autobe-specification":
|
|
256
|
-
"JWT token information for authentication. Server generates this token upon successful login/join.",
|
|
257
|
-
description: "JWT token information for authentication.",
|
|
258
|
-
$ref: "#/components/schemas/IAuthorizationToken",
|
|
259
|
-
} as AutoBeOpenApi.IJsonSchemaProperty.IReference;
|
|
260
|
-
|
|
261
|
-
props.schema.required ??= [];
|
|
262
|
-
if (props.schema.required.includes("token") === false)
|
|
263
|
-
props.schema.required.push("token");
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
AutoBeOpenApiTypeChecker.skim({
|
|
268
|
-
schema: props.schema,
|
|
269
|
-
accessor: props.path,
|
|
270
|
-
closure: (next, accessor) => {
|
|
271
|
-
if (AutoBeOpenApiTypeChecker.isReference(next) === false) return;
|
|
272
|
-
const key: string = next.$ref.split("/").pop()!;
|
|
273
|
-
if (
|
|
274
|
-
key.endsWith(".IAuthorized") === false &&
|
|
275
|
-
key.endsWith(".ILogin") === false &&
|
|
276
|
-
key.endsWith(".IJoin") === false
|
|
277
|
-
)
|
|
278
|
-
return;
|
|
279
|
-
const candidates: Set<string> = new Set(
|
|
280
|
-
props.operations
|
|
281
|
-
.map((op) => [
|
|
282
|
-
op.requestBody?.typeName.endsWith(key.split(".").pop()!)
|
|
283
|
-
? op.requestBody!.typeName
|
|
284
|
-
: null,
|
|
285
|
-
op.responseBody?.typeName.endsWith(key.split(".").pop()!)
|
|
286
|
-
? op.responseBody!.typeName
|
|
287
|
-
: null,
|
|
288
|
-
])
|
|
289
|
-
.flat()
|
|
290
|
-
.filter((v) => v !== null),
|
|
291
|
-
);
|
|
292
|
-
if (candidates.has(key) === false)
|
|
293
|
-
props.errors.push({
|
|
294
|
-
path: `${accessor}.$ref`,
|
|
295
|
-
expected: Array.from(candidates)
|
|
296
|
-
.map((s) => JSON.stringify(`#/components/schemas/${s}`))
|
|
297
|
-
.join(" | "),
|
|
298
|
-
value: key,
|
|
299
|
-
description: StringUtil.trim`
|
|
300
|
-
You've referenced an authorization-related type ${JSON.stringify(key)}
|
|
301
|
-
that is not used in any operation's requestBody or responseBody.
|
|
302
|
-
|
|
303
|
-
Authorization-related types must be used in at least one operation's
|
|
304
|
-
requestBody or responseBody. Make sure to use the type appropriately
|
|
305
|
-
in your API design.
|
|
306
|
-
|
|
307
|
-
Existing authorization-related types used in operations are:
|
|
308
|
-
- ${Array.from(candidates)
|
|
309
|
-
.map((s) => `#/components/schemas/${s}`)
|
|
310
|
-
.join("\n- ")}
|
|
311
|
-
|
|
312
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
313
|
-
`,
|
|
314
|
-
});
|
|
315
|
-
},
|
|
316
|
-
});
|
|
317
|
-
};
|
|
318
|
-
|
|
319
|
-
const validateRecursive = (props: IProps): void => {
|
|
320
|
-
const report = (description: string) =>
|
|
321
|
-
props.errors.push({
|
|
322
|
-
path: props.path,
|
|
323
|
-
expected: "Non-infinite recursive schema definition",
|
|
324
|
-
value: props.schema,
|
|
325
|
-
description,
|
|
326
|
-
});
|
|
327
|
-
if (
|
|
328
|
-
AutoBeOpenApiTypeChecker.isReference(props.schema) &&
|
|
329
|
-
props.schema.$ref === `#/components/schemas/${props.typeName}`
|
|
330
|
-
)
|
|
331
|
-
report(StringUtil.trim`
|
|
332
|
-
You have defined a nonsensible type like below:
|
|
333
|
-
|
|
334
|
-
\`\`\`typescript
|
|
335
|
-
type ${props.typeName} = ${props.typeName};
|
|
336
|
-
\`\`\`
|
|
337
|
-
|
|
338
|
-
This is an infinite recursive type definition that cannot exist in any
|
|
339
|
-
programming language. A type cannot be defined as itself - this creates
|
|
340
|
-
a circular definition with no base case, making the type impossible to
|
|
341
|
-
instantiate or validate.
|
|
342
|
-
|
|
343
|
-
If you need tree or graph structures, use explicit relationships with
|
|
344
|
-
ID references (e.g., parentId: string) instead of recursive type definitions.
|
|
345
|
-
Remove the self-reference and redesign the schema at the next time.
|
|
346
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
347
|
-
`);
|
|
348
|
-
else if (
|
|
349
|
-
AutoBeOpenApiTypeChecker.isArray(props.schema) &&
|
|
350
|
-
AutoBeOpenApiTypeChecker.isReference(props.schema.items) &&
|
|
351
|
-
props.schema.items.$ref === `#/components/schemas/${props.typeName}`
|
|
352
|
-
)
|
|
353
|
-
report(StringUtil.trim`
|
|
354
|
-
You have defined a nonsensible type like below:
|
|
355
|
-
|
|
356
|
-
\`\`\`typescript
|
|
357
|
-
type ${props.typeName} = Array<${props.typeName}>;
|
|
358
|
-
\`\`\`
|
|
359
|
-
|
|
360
|
-
This is an infinite recursive array type that cannot exist in any
|
|
361
|
-
programming language. An array of itself creates a circular definition
|
|
362
|
-
with no base case, making the type impossible to instantiate or validate.
|
|
363
|
-
|
|
364
|
-
If you need nested structures, define explicit depth levels with separate
|
|
365
|
-
types, or use parent-child relationships with ID references.
|
|
366
|
-
Remove the self-reference and redesign the schema at the next time.
|
|
367
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
368
|
-
`);
|
|
369
|
-
else if (
|
|
370
|
-
AutoBeOpenApiTypeChecker.isOneOf(props.schema) &&
|
|
371
|
-
props.schema.oneOf.some(
|
|
372
|
-
(v) =>
|
|
373
|
-
AutoBeOpenApiTypeChecker.isReference(v) &&
|
|
374
|
-
v.$ref === `#/components/schemas/${props.typeName}`,
|
|
375
|
-
) === true
|
|
376
|
-
)
|
|
377
|
-
report(StringUtil.trim`
|
|
378
|
-
You have defined a nonsensible type like below:
|
|
379
|
-
|
|
380
|
-
\`\`\`typescript
|
|
381
|
-
type ${props.typeName} = ${props.typeName} | ...;
|
|
382
|
-
\`\`\`
|
|
383
|
-
|
|
384
|
-
This is an infinite recursive union type that cannot exist in any
|
|
385
|
-
programming language. A union that includes itself as a variant creates
|
|
386
|
-
a circular definition with no base case, making the type impossible to
|
|
387
|
-
instantiate or validate.
|
|
388
|
-
|
|
389
|
-
If you need polymorphic hierarchies, define separate concrete types for
|
|
390
|
-
each variant without including the union type itself as a variant.
|
|
391
|
-
Remove the self-reference and redesign the schema at the next time.
|
|
392
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
393
|
-
`);
|
|
394
|
-
else if (
|
|
395
|
-
AutoBeOpenApiTypeChecker.isObject(props.schema) &&
|
|
396
|
-
props.schema.properties &&
|
|
397
|
-
props.schema.required &&
|
|
398
|
-
Object.entries(props.schema.properties).some(
|
|
399
|
-
([k, v]) =>
|
|
400
|
-
AutoBeOpenApiTypeChecker.isReference(v) &&
|
|
401
|
-
v.$ref === `#/components/schemas/${props.typeName}` &&
|
|
402
|
-
(props.schema as AutoBeOpenApi.IJsonSchema.IObject).required.includes(
|
|
403
|
-
k,
|
|
404
|
-
),
|
|
405
|
-
)
|
|
406
|
-
)
|
|
407
|
-
report(StringUtil.trim`
|
|
408
|
-
You have defined a nonsensible type like below:
|
|
409
|
-
|
|
410
|
-
\`\`\`typescript
|
|
411
|
-
interface ${props.typeName} {
|
|
412
|
-
someProperty: ${props.typeName}; // required, non-nullable
|
|
413
|
-
}
|
|
414
|
-
\`\`\`
|
|
415
|
-
|
|
416
|
-
This is an infinite recursive object type that cannot exist in any
|
|
417
|
-
programming language. A required non-nullable property referencing its
|
|
418
|
-
own type creates a circular definition with no base case, making the
|
|
419
|
-
type impossible to instantiate.
|
|
420
|
-
|
|
421
|
-
To create an instance of ${props.typeName}, you would need an instance of ${props.typeName},
|
|
422
|
-
which requires another instance of ${props.typeName}, infinitely. This is logically
|
|
423
|
-
impossible.
|
|
424
|
-
|
|
425
|
-
If you need parent-child or graph relationships, make the self-referencing
|
|
426
|
-
property either nullable or optional, or use ID references (e.g., parentId: string).
|
|
427
|
-
Remove the required self-reference and redesign the schema at the next time.
|
|
428
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
429
|
-
`);
|
|
430
|
-
};
|
|
431
|
-
|
|
432
|
-
const validateObjectType = (props: {
|
|
433
|
-
errors: IValidation.IError[];
|
|
434
|
-
operations: AutoBeOpenApi.IOperation[];
|
|
435
|
-
path: string;
|
|
436
|
-
}) => {
|
|
437
|
-
const root: Set<string> = new Set();
|
|
438
|
-
for (const o of props.operations) {
|
|
439
|
-
if (o.requestBody) root.add(o.requestBody.typeName);
|
|
440
|
-
if (o.responseBody) root.add(o.responseBody.typeName);
|
|
441
|
-
}
|
|
442
|
-
return (key: string, schema: AutoBeOpenApi.IJsonSchema): void => {
|
|
443
|
-
if (AutoBeOpenApiTypeChecker.isObject(schema) === true) return;
|
|
444
|
-
if (root.has(key))
|
|
445
|
-
props.errors.push({
|
|
446
|
-
path: props.path,
|
|
447
|
-
expected: `AutoBeOpenApi.IJsonSchemaDescriptive.IObject`,
|
|
448
|
-
value: schema,
|
|
449
|
-
description: StringUtil.trim`
|
|
450
|
-
Root schema types (used in requestBody or responseBody of operations)
|
|
451
|
-
must be defined as object types.
|
|
452
|
-
|
|
453
|
-
This is the rule enforced to ensure consistent API design and to facilitate easier data handling.
|
|
454
|
-
Even though you think that defining a non-object type is more convenient for your specific use case,
|
|
455
|
-
just follow the rule without any resistance.
|
|
456
|
-
|
|
457
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
458
|
-
|
|
459
|
-
If current type is hard to be defined as an object type, just wrap it in an object type like below:
|
|
460
|
-
|
|
461
|
-
\`\`\`typescript
|
|
462
|
-
{
|
|
463
|
-
value: T;
|
|
464
|
-
}
|
|
465
|
-
\`\`\`
|
|
466
|
-
`,
|
|
467
|
-
});
|
|
468
|
-
else if (
|
|
469
|
-
key.endsWith(".IRequest") ||
|
|
470
|
-
key.endsWith(".ISummary") ||
|
|
471
|
-
key.endsWith(".IInvert") ||
|
|
472
|
-
key.endsWith(".ICreate") ||
|
|
473
|
-
key.endsWith(".IUpdate") ||
|
|
474
|
-
key.endsWith(".IJoin") ||
|
|
475
|
-
key.endsWith(".ILogin") ||
|
|
476
|
-
key.endsWith(".IAuthorized")
|
|
477
|
-
)
|
|
478
|
-
props.errors.push({
|
|
479
|
-
path: props.path,
|
|
480
|
-
expected: `AutoBeOpenApi.IJsonSchemaDescriptive.IObject`,
|
|
481
|
-
value: schema,
|
|
482
|
-
description: StringUtil.trim`
|
|
483
|
-
DTO type of .${key.split(".").pop()} suffix must be defined as an object type.
|
|
484
|
-
|
|
485
|
-
This is the rule enforced to ensure consistent API design and to facilitate easier data handling.
|
|
486
|
-
Even though you think that defining a non-object type is more convenient for your specific use case,
|
|
487
|
-
just follow the rule without any resistance.
|
|
488
|
-
|
|
489
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
490
|
-
|
|
491
|
-
If current type is hard to be defined as an object type, just wrap it in an object type like below:
|
|
492
|
-
|
|
493
|
-
\`\`\`typescript
|
|
494
|
-
{
|
|
495
|
-
value: T;
|
|
496
|
-
}
|
|
497
|
-
\`\`\`
|
|
498
|
-
`,
|
|
499
|
-
});
|
|
500
|
-
};
|
|
501
|
-
};
|
|
502
|
-
|
|
503
|
-
const validateReferenceId = (props: {
|
|
504
|
-
errors: IValidation.IError[];
|
|
505
|
-
schema: AutoBeOpenApi.IJsonSchema;
|
|
506
|
-
path: string;
|
|
507
|
-
}): void => {
|
|
508
|
-
if (AutoBeOpenApiTypeChecker.isObject(props.schema) === false) return;
|
|
509
|
-
for (const [key, value] of Object.entries(props.schema.properties)) {
|
|
510
|
-
if (key !== "id" && key.endsWith("_id") === false) continue;
|
|
511
|
-
|
|
512
|
-
const accessor: string = `${props.path}.properties${
|
|
513
|
-
NamingConvention.variable(key) ? `.${key}` : `[${JSON.stringify(key)}]`
|
|
514
|
-
}`;
|
|
515
|
-
const inspect = (schema: AutoBeOpenApi.IJsonSchema): boolean =>
|
|
516
|
-
AutoBeOpenApiTypeChecker.isString(schema) ||
|
|
517
|
-
AutoBeOpenApiTypeChecker.isNull(schema) ||
|
|
518
|
-
(AutoBeOpenApiTypeChecker.isOneOf(schema) &&
|
|
519
|
-
schema.oneOf.every((v) => inspect(v)));
|
|
520
|
-
if (inspect(value) === false)
|
|
521
|
-
props.errors.push({
|
|
522
|
-
path: accessor,
|
|
523
|
-
expected: StringUtil.trim`
|
|
524
|
-
| { type: "string"; format: "uuid"; description: string; }
|
|
525
|
-
| {
|
|
526
|
-
oneOf: [
|
|
527
|
-
{ type: "string"; format: "uuid"; },
|
|
528
|
-
{ type: "null"; },
|
|
529
|
-
];
|
|
530
|
-
description: string;
|
|
531
|
-
}`,
|
|
532
|
-
value,
|
|
533
|
-
description: StringUtil.trim`
|
|
534
|
-
Property names "id" or ending with "_id" must be defined as
|
|
535
|
-
UUID string type, or nullable UUID string type.
|
|
536
|
-
|
|
537
|
-
This is the rule enforced to ensure consistent identification of
|
|
538
|
-
resources across the API. Even though you think that defining a
|
|
539
|
-
different type is more convenient for your specific use case,
|
|
540
|
-
just follow the rule without any resistance.
|
|
541
|
-
|
|
542
|
-
Note that, this is not a recommendation, but an instruction you
|
|
543
|
-
must follow.
|
|
544
|
-
`,
|
|
545
|
-
});
|
|
546
|
-
}
|
|
547
|
-
};
|
|
548
|
-
|
|
549
|
-
const validatePropertyNames = (props: {
|
|
550
|
-
errors: IValidation.IError[];
|
|
551
|
-
schema: AutoBeOpenApi.IJsonSchema;
|
|
552
|
-
path: string;
|
|
553
|
-
}): void => {
|
|
554
|
-
if (AutoBeOpenApiTypeChecker.isObject(props.schema) === false) return;
|
|
555
|
-
for (const key of Object.keys(props.schema.properties)) {
|
|
556
|
-
if (NamingConvention.reserved(key))
|
|
557
|
-
props.errors.push({
|
|
558
|
-
path: `${props.path}.properties${NamingConvention.variable(key) ? `.${key}` : `[${JSON.stringify(key)}]`}`,
|
|
559
|
-
expected: `none system reserved word`,
|
|
560
|
-
value: key,
|
|
561
|
-
description: StringUtil.trim`
|
|
562
|
-
Property name ${JSON.stringify(key)} is a system reserved word.
|
|
563
|
-
|
|
564
|
-
Avoid using system reserved words as property names to prevent
|
|
565
|
-
potential conflicts and ensure clarity in your API design.
|
|
566
|
-
|
|
567
|
-
Change the property name ${JSON.stringify(key)} to a non-reserved
|
|
568
|
-
word at the next time.
|
|
569
|
-
|
|
570
|
-
Note that, this is not a recommendation, but an instruction you
|
|
571
|
-
must follow.
|
|
572
|
-
`,
|
|
573
|
-
});
|
|
574
|
-
else if (NamingConvention.variable(key) === false)
|
|
575
|
-
props.errors.push({
|
|
576
|
-
path: `${props.path}.properties${NamingConvention.variable(key) ? `.${key}` : `[${JSON.stringify(key)}]`}`,
|
|
577
|
-
expected: `valid variable name`,
|
|
578
|
-
value: key,
|
|
579
|
-
description: StringUtil.trim`
|
|
580
|
-
Property name ${JSON.stringify(key)} must be a valid variable name.
|
|
581
|
-
|
|
582
|
-
Valid variable names start with a letter, underscore (_), or dollar sign ($),
|
|
583
|
-
followed by letters, digits, underscores, or dollar signs. They cannot
|
|
584
|
-
contain spaces or special characters.
|
|
585
|
-
|
|
586
|
-
Change the property name ${JSON.stringify(key)} to a valid variable
|
|
587
|
-
name at the next time.
|
|
588
|
-
|
|
589
|
-
Note that, this is not a recommendation, but an instruction you
|
|
590
|
-
must follow.
|
|
591
|
-
`,
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
};
|
|
595
|
-
|
|
596
|
-
const validateNumericRanges = (props: IProps): void => {
|
|
597
|
-
AutoBeOpenApiTypeChecker.skim({
|
|
598
|
-
schema: props.schema,
|
|
599
|
-
accessor: `${props.path}[${JSON.stringify(props.typeName)}]`,
|
|
600
|
-
closure: (schema, accessor) => {
|
|
601
|
-
if (
|
|
602
|
-
AutoBeOpenApiTypeChecker.isInteger(schema) === false &&
|
|
603
|
-
AutoBeOpenApiTypeChecker.isNumber(schema) === false
|
|
604
|
-
)
|
|
605
|
-
return;
|
|
606
|
-
|
|
607
|
-
const { minimum, maximum, exclusiveMinimum, exclusiveMaximum } = schema;
|
|
608
|
-
|
|
609
|
-
// Case 1: minimum > maximum
|
|
610
|
-
if (minimum !== undefined && maximum !== undefined && minimum > maximum)
|
|
611
|
-
props.errors.push({
|
|
612
|
-
path: accessor,
|
|
613
|
-
expected: "minimum <= maximum",
|
|
614
|
-
value: schema,
|
|
615
|
-
description: StringUtil.trim`
|
|
616
|
-
Invalid numeric range: minimum (${minimum}) is greater than maximum (${maximum}).
|
|
617
|
-
|
|
618
|
-
This creates an impossible range where no value can satisfy both constraints.
|
|
619
|
-
Either increase maximum or decrease minimum to create a valid range.
|
|
620
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
621
|
-
`,
|
|
622
|
-
});
|
|
623
|
-
|
|
624
|
-
// Case 2: exclusiveMinimum >= exclusiveMaximum
|
|
625
|
-
if (
|
|
626
|
-
exclusiveMinimum !== undefined &&
|
|
627
|
-
exclusiveMaximum !== undefined &&
|
|
628
|
-
exclusiveMinimum >= exclusiveMaximum
|
|
629
|
-
)
|
|
630
|
-
props.errors.push({
|
|
631
|
-
path: accessor,
|
|
632
|
-
expected: "exclusiveMinimum < exclusiveMaximum",
|
|
633
|
-
value: schema,
|
|
634
|
-
description: StringUtil.trim`
|
|
635
|
-
Invalid numeric range: exclusiveMinimum (${exclusiveMinimum}) is greater than
|
|
636
|
-
or equal to exclusiveMaximum (${exclusiveMaximum}).
|
|
637
|
-
|
|
638
|
-
This creates an impossible range where no value can satisfy both constraints.
|
|
639
|
-
Either increase exclusiveMaximum or decrease exclusiveMinimum to create a valid range.
|
|
640
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
641
|
-
`,
|
|
642
|
-
});
|
|
643
|
-
|
|
644
|
-
// Case 3: minimum >= exclusiveMaximum
|
|
645
|
-
if (
|
|
646
|
-
minimum !== undefined &&
|
|
647
|
-
exclusiveMaximum !== undefined &&
|
|
648
|
-
minimum >= exclusiveMaximum
|
|
649
|
-
)
|
|
650
|
-
props.errors.push({
|
|
651
|
-
path: accessor,
|
|
652
|
-
expected: "minimum < exclusiveMaximum",
|
|
653
|
-
value: schema,
|
|
654
|
-
description: StringUtil.trim`
|
|
655
|
-
Invalid numeric range: minimum (${minimum}) is greater than or equal to
|
|
656
|
-
exclusiveMaximum (${exclusiveMaximum}).
|
|
657
|
-
|
|
658
|
-
This creates an impossible range. A value cannot be >= ${minimum} and < ${exclusiveMaximum}
|
|
659
|
-
at the same time when minimum >= exclusiveMaximum.
|
|
660
|
-
Either increase exclusiveMaximum or decrease minimum to create a valid range.
|
|
661
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
662
|
-
`,
|
|
663
|
-
});
|
|
664
|
-
|
|
665
|
-
// Case 4: exclusiveMinimum >= maximum
|
|
666
|
-
if (
|
|
667
|
-
exclusiveMinimum !== undefined &&
|
|
668
|
-
maximum !== undefined &&
|
|
669
|
-
exclusiveMinimum >= maximum
|
|
670
|
-
)
|
|
671
|
-
props.errors.push({
|
|
672
|
-
path: accessor,
|
|
673
|
-
expected: "exclusiveMinimum < maximum",
|
|
674
|
-
value: schema,
|
|
675
|
-
description: StringUtil.trim`
|
|
676
|
-
Invalid numeric range: exclusiveMinimum (${exclusiveMinimum}) is greater than
|
|
677
|
-
or equal to maximum (${maximum}).
|
|
678
|
-
|
|
679
|
-
This creates an impossible range. A value cannot be > ${exclusiveMinimum} and <= ${maximum}
|
|
680
|
-
at the same time when exclusiveMinimum >= maximum.
|
|
681
|
-
Either increase maximum or decrease exclusiveMinimum to create a valid range.
|
|
682
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
683
|
-
`,
|
|
684
|
-
});
|
|
685
|
-
|
|
686
|
-
// Case 5: minimum === maximum with exclusive constraints
|
|
687
|
-
if (
|
|
688
|
-
minimum !== undefined &&
|
|
689
|
-
maximum !== undefined &&
|
|
690
|
-
minimum === maximum &&
|
|
691
|
-
(exclusiveMinimum !== undefined || exclusiveMaximum !== undefined)
|
|
692
|
-
)
|
|
693
|
-
props.errors.push({
|
|
694
|
-
path: accessor,
|
|
695
|
-
expected: "no exclusive constraints when minimum equals maximum",
|
|
696
|
-
value: schema,
|
|
697
|
-
description: StringUtil.trim`
|
|
698
|
-
Invalid numeric range: minimum equals maximum (${minimum}), but exclusive
|
|
699
|
-
constraints are also defined.
|
|
700
|
-
|
|
701
|
-
When minimum === maximum, the only valid value is exactly ${minimum}.
|
|
702
|
-
Adding exclusiveMinimum or exclusiveMaximum makes this impossible.
|
|
703
|
-
Remove the exclusive constraints or adjust minimum/maximum to create a valid range.
|
|
704
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
705
|
-
`,
|
|
706
|
-
});
|
|
707
|
-
|
|
708
|
-
// Case 6: negative multipleOf
|
|
709
|
-
if (schema.multipleOf !== undefined && schema.multipleOf <= 0)
|
|
710
|
-
props.errors.push({
|
|
711
|
-
path: accessor,
|
|
712
|
-
expected: "multipleOf > 0",
|
|
713
|
-
value: schema,
|
|
714
|
-
description: StringUtil.trim`
|
|
715
|
-
Invalid multipleOf value: ${schema.multipleOf}.
|
|
716
|
-
|
|
717
|
-
The multipleOf constraint must be a positive number greater than zero.
|
|
718
|
-
Change multipleOf to a positive value.
|
|
719
|
-
Note that, this is not a recommendation, but an instruction you must follow.
|
|
720
|
-
`,
|
|
721
|
-
});
|
|
722
|
-
},
|
|
723
|
-
});
|
|
724
|
-
};
|
|
725
|
-
}
|
|
1
|
+
import { AutoBeOpenApi } from "@autobe/interface";
|
|
2
|
+
import { AutoBeOpenApiTypeChecker, StringUtil } from "@autobe/utils";
|
|
3
|
+
import { NamingConvention } from "@typia/utils";
|
|
4
|
+
import { IValidation } from "typia";
|
|
5
|
+
|
|
6
|
+
import { AutoBeJsonSchemaFactory } from "./AutoBeJsonSchemaFactory";
|
|
7
|
+
|
|
8
|
+
export namespace AutoBeJsonSchemaValidator {
|
|
9
|
+
export const isObjectType = (props: {
|
|
10
|
+
operations: AutoBeOpenApi.IOperation[];
|
|
11
|
+
typeName: string;
|
|
12
|
+
}): boolean =>
|
|
13
|
+
props.typeName.endsWith(".IAuthorized") ||
|
|
14
|
+
props.typeName.endsWith(".IRequest") ||
|
|
15
|
+
props.typeName.endsWith(".ISummary") ||
|
|
16
|
+
props.typeName.endsWith(".IInvert") ||
|
|
17
|
+
props.typeName.endsWith(".ICreate") ||
|
|
18
|
+
props.typeName.endsWith(".IUpdate") ||
|
|
19
|
+
props.typeName.endsWith(".IJoin") ||
|
|
20
|
+
props.typeName.endsWith(".ILogin") ||
|
|
21
|
+
props.operations.some(
|
|
22
|
+
(op) =>
|
|
23
|
+
op.requestBody?.typeName === props.typeName ||
|
|
24
|
+
op.responseBody?.typeName === props.typeName,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
export const isPage = (key: string): boolean =>
|
|
28
|
+
key.startsWith("IPage") === true &&
|
|
29
|
+
key.startsWith("IPage.") === false &&
|
|
30
|
+
key !== "IPage";
|
|
31
|
+
|
|
32
|
+
export const isPreset = (typeName: string): boolean =>
|
|
33
|
+
AutoBeJsonSchemaFactory.DEFAULT_SCHEMAS[typeName] !== undefined ||
|
|
34
|
+
AutoBeJsonSchemaValidator.isPage(typeName) === true;
|
|
35
|
+
|
|
36
|
+
export interface IProps {
|
|
37
|
+
errors: IValidation.IError[];
|
|
38
|
+
operations: AutoBeOpenApi.IOperation[];
|
|
39
|
+
typeName: string;
|
|
40
|
+
schema: AutoBeOpenApi.IJsonSchema;
|
|
41
|
+
path: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const validateSchema = (props: IProps): void => {
|
|
45
|
+
const vo = validateObjectType({
|
|
46
|
+
errors: props.errors,
|
|
47
|
+
operations: props.operations,
|
|
48
|
+
path: props.path,
|
|
49
|
+
});
|
|
50
|
+
validateAuthorization(props);
|
|
51
|
+
validateRecursive(props);
|
|
52
|
+
validateReferenceId(props);
|
|
53
|
+
validatePropertyNames(props);
|
|
54
|
+
validateNumericRanges(props);
|
|
55
|
+
|
|
56
|
+
vo(props.typeName, props.schema);
|
|
57
|
+
AutoBeOpenApiTypeChecker.skim({
|
|
58
|
+
schema: props.schema,
|
|
59
|
+
closure: (next, accessor) => {
|
|
60
|
+
if (AutoBeOpenApiTypeChecker.isReference(next) === false) return;
|
|
61
|
+
const key: string = next.$ref.split("/").pop()!;
|
|
62
|
+
validateKey({
|
|
63
|
+
errors: props.errors,
|
|
64
|
+
path: `${accessor}.$ref`,
|
|
65
|
+
key,
|
|
66
|
+
transform: (typeName) => `#/components/schemas/${typeName}`,
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
accessor: props.path,
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const validateKey = (props: {
|
|
74
|
+
errors: IValidation.IError[];
|
|
75
|
+
key: string;
|
|
76
|
+
path: string;
|
|
77
|
+
transform?: (typeName: string) => string;
|
|
78
|
+
}): void => {
|
|
79
|
+
const transform = props.transform ?? ((typeName: string) => typeName);
|
|
80
|
+
const elements: string[] = props.key.split(".");
|
|
81
|
+
if (elements.length > 2)
|
|
82
|
+
props.errors.push({
|
|
83
|
+
path: props.path,
|
|
84
|
+
expected: "At most one dot(.) character allowed in type name",
|
|
85
|
+
value: transform(props.key),
|
|
86
|
+
description: StringUtil.trim`
|
|
87
|
+
JSON schema type name allows at most one dot(.) character to separate
|
|
88
|
+
module name and interface name.
|
|
89
|
+
|
|
90
|
+
However, current key name ${transform(JSON.stringify(props.key))}
|
|
91
|
+
contains multiple dot(.) characters (${elements.length - 1} times).
|
|
92
|
+
|
|
93
|
+
Change it to a valid type name with at most one dot(.) character at the next time.
|
|
94
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
95
|
+
`,
|
|
96
|
+
});
|
|
97
|
+
if (elements.every(NamingConvention.variable) === false)
|
|
98
|
+
props.errors.push({
|
|
99
|
+
path: props.path,
|
|
100
|
+
expected: StringUtil.trim`
|
|
101
|
+
Valid variable name
|
|
102
|
+
|
|
103
|
+
${elements.map((s) => `- ${s}: ${NamingConvention.variable(s) ? "valid" : "invalid"}`).join("\n")}
|
|
104
|
+
`,
|
|
105
|
+
value: transform(props.key),
|
|
106
|
+
description: StringUtil.trim`
|
|
107
|
+
JSON schema type name must be a valid variable name.
|
|
108
|
+
|
|
109
|
+
Even though JSON schema type name allows dot(.) character, but
|
|
110
|
+
each segment separated by dot(.) must be a valid variable name.
|
|
111
|
+
|
|
112
|
+
Current key name ${transform(JSON.stringify(props.key))} is not valid.
|
|
113
|
+
Change it to a valid variable name at the next time.
|
|
114
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
115
|
+
`,
|
|
116
|
+
});
|
|
117
|
+
if (props.key.endsWith(".IPage")) {
|
|
118
|
+
const expected: string = `IPage${props.key.substring(0, props.key.length - 6)}`;
|
|
119
|
+
props.errors.push({
|
|
120
|
+
path: props.path,
|
|
121
|
+
expected: `"IPage" must be followed by another interface name. Use ${transform(JSON.stringify(expected))} instead.`,
|
|
122
|
+
value: transform(props.key),
|
|
123
|
+
description: StringUtil.trim`
|
|
124
|
+
"IPage" is a reserved type name for pagination response.
|
|
125
|
+
The pagination data type name must be post-fixed after "IPage".
|
|
126
|
+
|
|
127
|
+
However, you've defined ${transform(JSON.stringify(props.key))},
|
|
128
|
+
post-fixing ".IPage" after the pagination data type name.
|
|
129
|
+
|
|
130
|
+
Change it to a valid pagination type name to be
|
|
131
|
+
${transform(JSON.stringify(expected))} at the next time.
|
|
132
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
133
|
+
`,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
if (props.key === "IPageIRequest")
|
|
137
|
+
props.errors.push({
|
|
138
|
+
path: props.path,
|
|
139
|
+
expected: `"IPageIRequest" is a mistake. Use "IPage.IRequest" instead.`,
|
|
140
|
+
value: transform(props.key),
|
|
141
|
+
description: StringUtil.trim`
|
|
142
|
+
You've taken a mistake that defines "${transform("IPageIRequest")}" as a type name.
|
|
143
|
+
However, as you've intended to define a pagination request type,
|
|
144
|
+
the correct type name is "${transform("IPage.IRequest")}" instead of "${transform("IPageIRequest")}".
|
|
145
|
+
|
|
146
|
+
Change it to "${transform("IPage.IRequest")}" at the next time.
|
|
147
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
148
|
+
`,
|
|
149
|
+
});
|
|
150
|
+
if (
|
|
151
|
+
props.key.startsWith("IPage") &&
|
|
152
|
+
props.key.startsWith("IPageI") === false &&
|
|
153
|
+
props.key !== "IPage.IPagination" &&
|
|
154
|
+
props.key !== "IPage.IRequest"
|
|
155
|
+
) {
|
|
156
|
+
const expected: string = `IPage${props.key
|
|
157
|
+
.substring(5)
|
|
158
|
+
.split(".")
|
|
159
|
+
.map((s) => (s.startsWith("I") ? s : `I${s}`))
|
|
160
|
+
.join(".")}`;
|
|
161
|
+
props.errors.push({
|
|
162
|
+
path: props.path,
|
|
163
|
+
expected: `Interface name starting with 'I' even after 'IPage': ${JSON.stringify(expected)}`,
|
|
164
|
+
value: transform(props.key),
|
|
165
|
+
description: StringUtil.trim`
|
|
166
|
+
JSON schema type name must be an interface name starting with 'I'.
|
|
167
|
+
Even though JSON schema type name allows dot(.) character, but
|
|
168
|
+
each segment separated by dot(.) must be an interface name starting
|
|
169
|
+
with 'I'.
|
|
170
|
+
|
|
171
|
+
Even in the case of pagination response, after 'IPage' prefix,
|
|
172
|
+
the remaining part must be an interface name starting with 'I'.
|
|
173
|
+
|
|
174
|
+
Current key name ${JSON.stringify(props.key)} is not valid. Change
|
|
175
|
+
it to a valid interface name to be ${JSON.stringify(expected)},
|
|
176
|
+
or change it to another valid interface name at the next time.
|
|
177
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
178
|
+
`,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
if (elements.some((s) => s.startsWith("I") === false) === true) {
|
|
182
|
+
const expected: string = elements
|
|
183
|
+
.map((s) => (s.startsWith("I") ? s : `I${s}`))
|
|
184
|
+
.join(".");
|
|
185
|
+
props.errors.push({
|
|
186
|
+
path: props.path,
|
|
187
|
+
expected: `Interface name starting with 'I': ${JSON.stringify(expected)}`,
|
|
188
|
+
value: transform(props.key),
|
|
189
|
+
description: StringUtil.trim`
|
|
190
|
+
JSON schema type name must be an interface name starting with 'I'.
|
|
191
|
+
Even though JSON schema type name allows dot(.) character, but
|
|
192
|
+
each segment separated by dot(.) must be an interface name starting
|
|
193
|
+
with 'I'.
|
|
194
|
+
|
|
195
|
+
Current key name ${transform(JSON.stringify(props.key))} is not valid.
|
|
196
|
+
Change it to a valid interface name to be ${transform(JSON.stringify(expected))},
|
|
197
|
+
or change it to another valid interface name at the next time.
|
|
198
|
+
|
|
199
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
200
|
+
`,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
if (
|
|
204
|
+
elements.length === 2 &&
|
|
205
|
+
(elements[1] === "IJoin" ||
|
|
206
|
+
elements[1] === "ILogin" ||
|
|
207
|
+
elements[1] === "IAuthorized" ||
|
|
208
|
+
elements[1] === "IRefresh") &&
|
|
209
|
+
elements[0].endsWith("Session") === true
|
|
210
|
+
)
|
|
211
|
+
props.errors.push({
|
|
212
|
+
path: props.path,
|
|
213
|
+
expected: JSON.stringify(
|
|
214
|
+
`${elements[0].replace("Session", "")}.${elements[1]}`,
|
|
215
|
+
),
|
|
216
|
+
value: transform(props.key),
|
|
217
|
+
description: StringUtil.trim`
|
|
218
|
+
You have attached ${elements[1]} to a Session type ${transform(JSON.stringify(props.key))},
|
|
219
|
+
but this is architecturally incorrect.
|
|
220
|
+
|
|
221
|
+
In production authentication systems, Actor and Session are separate concepts:
|
|
222
|
+
- **Actor** (e.g., User, Seller, Admin): The persistent user identity that performs
|
|
223
|
+
authentication actions - joining (registering), logging in, and receiving authorized tokens.
|
|
224
|
+
- **Session** (e.g., UserSession, SellerSession): The temporary authentication state that
|
|
225
|
+
tracks active login instances. Sessions are CREATED as a result of join/login operations,
|
|
226
|
+
but they do not perform these actions themselves.
|
|
227
|
+
|
|
228
|
+
Think about it semantically: An ACTOR joins the system and logs in. A SESSION is merely
|
|
229
|
+
a record that gets created when the actor authenticates. It makes no sense for a session
|
|
230
|
+
to "join" or "login" - only actors do that.
|
|
231
|
+
|
|
232
|
+
Therefore, authentication-related DTO types (IJoin, ILogin, IAuthorized, IRefresh) MUST
|
|
233
|
+
be attached to the Actor type, NEVER to the Session type.
|
|
234
|
+
|
|
235
|
+
Change ${transform(JSON.stringify(props.key))} to ${transform(JSON.stringify(`${elements[0].replace("Session", "")}.${elements[1]}`))} at the next time.
|
|
236
|
+
|
|
237
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
238
|
+
`,
|
|
239
|
+
});
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const validateAuthorization = (props: IProps): void => {
|
|
243
|
+
if (props.typeName.endsWith(".IAuthorized") === true) {
|
|
244
|
+
if (AutoBeOpenApiTypeChecker.isObject(props.schema) === false) {
|
|
245
|
+
props.errors.push({
|
|
246
|
+
path: props.path,
|
|
247
|
+
expected: `AutoBeOpenApi.IJsonSchemaDescriptive<AutoBeOpenApi.IJsonSchema.IObject>`,
|
|
248
|
+
value: props.schema,
|
|
249
|
+
description: `${props.typeName} must be an object type for authorization responses. Note that, this is not a recommendation, but an instruction you must follow.`,
|
|
250
|
+
});
|
|
251
|
+
} else {
|
|
252
|
+
// Check if token property exists
|
|
253
|
+
props.schema.properties ??= {};
|
|
254
|
+
props.schema.properties["token"] = {
|
|
255
|
+
"x-autobe-specification":
|
|
256
|
+
"JWT token information for authentication. Server generates this token upon successful login/join.",
|
|
257
|
+
description: "JWT token information for authentication.",
|
|
258
|
+
$ref: "#/components/schemas/IAuthorizationToken",
|
|
259
|
+
} as AutoBeOpenApi.IJsonSchemaProperty.IReference;
|
|
260
|
+
|
|
261
|
+
props.schema.required ??= [];
|
|
262
|
+
if (props.schema.required.includes("token") === false)
|
|
263
|
+
props.schema.required.push("token");
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
AutoBeOpenApiTypeChecker.skim({
|
|
268
|
+
schema: props.schema,
|
|
269
|
+
accessor: props.path,
|
|
270
|
+
closure: (next, accessor) => {
|
|
271
|
+
if (AutoBeOpenApiTypeChecker.isReference(next) === false) return;
|
|
272
|
+
const key: string = next.$ref.split("/").pop()!;
|
|
273
|
+
if (
|
|
274
|
+
key.endsWith(".IAuthorized") === false &&
|
|
275
|
+
key.endsWith(".ILogin") === false &&
|
|
276
|
+
key.endsWith(".IJoin") === false
|
|
277
|
+
)
|
|
278
|
+
return;
|
|
279
|
+
const candidates: Set<string> = new Set(
|
|
280
|
+
props.operations
|
|
281
|
+
.map((op) => [
|
|
282
|
+
op.requestBody?.typeName.endsWith(key.split(".").pop()!)
|
|
283
|
+
? op.requestBody!.typeName
|
|
284
|
+
: null,
|
|
285
|
+
op.responseBody?.typeName.endsWith(key.split(".").pop()!)
|
|
286
|
+
? op.responseBody!.typeName
|
|
287
|
+
: null,
|
|
288
|
+
])
|
|
289
|
+
.flat()
|
|
290
|
+
.filter((v) => v !== null),
|
|
291
|
+
);
|
|
292
|
+
if (candidates.has(key) === false)
|
|
293
|
+
props.errors.push({
|
|
294
|
+
path: `${accessor}.$ref`,
|
|
295
|
+
expected: Array.from(candidates)
|
|
296
|
+
.map((s) => JSON.stringify(`#/components/schemas/${s}`))
|
|
297
|
+
.join(" | "),
|
|
298
|
+
value: key,
|
|
299
|
+
description: StringUtil.trim`
|
|
300
|
+
You've referenced an authorization-related type ${JSON.stringify(key)}
|
|
301
|
+
that is not used in any operation's requestBody or responseBody.
|
|
302
|
+
|
|
303
|
+
Authorization-related types must be used in at least one operation's
|
|
304
|
+
requestBody or responseBody. Make sure to use the type appropriately
|
|
305
|
+
in your API design.
|
|
306
|
+
|
|
307
|
+
Existing authorization-related types used in operations are:
|
|
308
|
+
- ${Array.from(candidates)
|
|
309
|
+
.map((s) => `#/components/schemas/${s}`)
|
|
310
|
+
.join("\n- ")}
|
|
311
|
+
|
|
312
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
313
|
+
`,
|
|
314
|
+
});
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
const validateRecursive = (props: IProps): void => {
|
|
320
|
+
const report = (description: string) =>
|
|
321
|
+
props.errors.push({
|
|
322
|
+
path: props.path,
|
|
323
|
+
expected: "Non-infinite recursive schema definition",
|
|
324
|
+
value: props.schema,
|
|
325
|
+
description,
|
|
326
|
+
});
|
|
327
|
+
if (
|
|
328
|
+
AutoBeOpenApiTypeChecker.isReference(props.schema) &&
|
|
329
|
+
props.schema.$ref === `#/components/schemas/${props.typeName}`
|
|
330
|
+
)
|
|
331
|
+
report(StringUtil.trim`
|
|
332
|
+
You have defined a nonsensible type like below:
|
|
333
|
+
|
|
334
|
+
\`\`\`typescript
|
|
335
|
+
type ${props.typeName} = ${props.typeName};
|
|
336
|
+
\`\`\`
|
|
337
|
+
|
|
338
|
+
This is an infinite recursive type definition that cannot exist in any
|
|
339
|
+
programming language. A type cannot be defined as itself - this creates
|
|
340
|
+
a circular definition with no base case, making the type impossible to
|
|
341
|
+
instantiate or validate.
|
|
342
|
+
|
|
343
|
+
If you need tree or graph structures, use explicit relationships with
|
|
344
|
+
ID references (e.g., parentId: string) instead of recursive type definitions.
|
|
345
|
+
Remove the self-reference and redesign the schema at the next time.
|
|
346
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
347
|
+
`);
|
|
348
|
+
else if (
|
|
349
|
+
AutoBeOpenApiTypeChecker.isArray(props.schema) &&
|
|
350
|
+
AutoBeOpenApiTypeChecker.isReference(props.schema.items) &&
|
|
351
|
+
props.schema.items.$ref === `#/components/schemas/${props.typeName}`
|
|
352
|
+
)
|
|
353
|
+
report(StringUtil.trim`
|
|
354
|
+
You have defined a nonsensible type like below:
|
|
355
|
+
|
|
356
|
+
\`\`\`typescript
|
|
357
|
+
type ${props.typeName} = Array<${props.typeName}>;
|
|
358
|
+
\`\`\`
|
|
359
|
+
|
|
360
|
+
This is an infinite recursive array type that cannot exist in any
|
|
361
|
+
programming language. An array of itself creates a circular definition
|
|
362
|
+
with no base case, making the type impossible to instantiate or validate.
|
|
363
|
+
|
|
364
|
+
If you need nested structures, define explicit depth levels with separate
|
|
365
|
+
types, or use parent-child relationships with ID references.
|
|
366
|
+
Remove the self-reference and redesign the schema at the next time.
|
|
367
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
368
|
+
`);
|
|
369
|
+
else if (
|
|
370
|
+
AutoBeOpenApiTypeChecker.isOneOf(props.schema) &&
|
|
371
|
+
props.schema.oneOf.some(
|
|
372
|
+
(v) =>
|
|
373
|
+
AutoBeOpenApiTypeChecker.isReference(v) &&
|
|
374
|
+
v.$ref === `#/components/schemas/${props.typeName}`,
|
|
375
|
+
) === true
|
|
376
|
+
)
|
|
377
|
+
report(StringUtil.trim`
|
|
378
|
+
You have defined a nonsensible type like below:
|
|
379
|
+
|
|
380
|
+
\`\`\`typescript
|
|
381
|
+
type ${props.typeName} = ${props.typeName} | ...;
|
|
382
|
+
\`\`\`
|
|
383
|
+
|
|
384
|
+
This is an infinite recursive union type that cannot exist in any
|
|
385
|
+
programming language. A union that includes itself as a variant creates
|
|
386
|
+
a circular definition with no base case, making the type impossible to
|
|
387
|
+
instantiate or validate.
|
|
388
|
+
|
|
389
|
+
If you need polymorphic hierarchies, define separate concrete types for
|
|
390
|
+
each variant without including the union type itself as a variant.
|
|
391
|
+
Remove the self-reference and redesign the schema at the next time.
|
|
392
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
393
|
+
`);
|
|
394
|
+
else if (
|
|
395
|
+
AutoBeOpenApiTypeChecker.isObject(props.schema) &&
|
|
396
|
+
props.schema.properties &&
|
|
397
|
+
props.schema.required &&
|
|
398
|
+
Object.entries(props.schema.properties).some(
|
|
399
|
+
([k, v]) =>
|
|
400
|
+
AutoBeOpenApiTypeChecker.isReference(v) &&
|
|
401
|
+
v.$ref === `#/components/schemas/${props.typeName}` &&
|
|
402
|
+
(props.schema as AutoBeOpenApi.IJsonSchema.IObject).required.includes(
|
|
403
|
+
k,
|
|
404
|
+
),
|
|
405
|
+
)
|
|
406
|
+
)
|
|
407
|
+
report(StringUtil.trim`
|
|
408
|
+
You have defined a nonsensible type like below:
|
|
409
|
+
|
|
410
|
+
\`\`\`typescript
|
|
411
|
+
interface ${props.typeName} {
|
|
412
|
+
someProperty: ${props.typeName}; // required, non-nullable
|
|
413
|
+
}
|
|
414
|
+
\`\`\`
|
|
415
|
+
|
|
416
|
+
This is an infinite recursive object type that cannot exist in any
|
|
417
|
+
programming language. A required non-nullable property referencing its
|
|
418
|
+
own type creates a circular definition with no base case, making the
|
|
419
|
+
type impossible to instantiate.
|
|
420
|
+
|
|
421
|
+
To create an instance of ${props.typeName}, you would need an instance of ${props.typeName},
|
|
422
|
+
which requires another instance of ${props.typeName}, infinitely. This is logically
|
|
423
|
+
impossible.
|
|
424
|
+
|
|
425
|
+
If you need parent-child or graph relationships, make the self-referencing
|
|
426
|
+
property either nullable or optional, or use ID references (e.g., parentId: string).
|
|
427
|
+
Remove the required self-reference and redesign the schema at the next time.
|
|
428
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
429
|
+
`);
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
const validateObjectType = (props: {
|
|
433
|
+
errors: IValidation.IError[];
|
|
434
|
+
operations: AutoBeOpenApi.IOperation[];
|
|
435
|
+
path: string;
|
|
436
|
+
}) => {
|
|
437
|
+
const root: Set<string> = new Set();
|
|
438
|
+
for (const o of props.operations) {
|
|
439
|
+
if (o.requestBody) root.add(o.requestBody.typeName);
|
|
440
|
+
if (o.responseBody) root.add(o.responseBody.typeName);
|
|
441
|
+
}
|
|
442
|
+
return (key: string, schema: AutoBeOpenApi.IJsonSchema): void => {
|
|
443
|
+
if (AutoBeOpenApiTypeChecker.isObject(schema) === true) return;
|
|
444
|
+
if (root.has(key))
|
|
445
|
+
props.errors.push({
|
|
446
|
+
path: props.path,
|
|
447
|
+
expected: `AutoBeOpenApi.IJsonSchemaDescriptive.IObject`,
|
|
448
|
+
value: schema,
|
|
449
|
+
description: StringUtil.trim`
|
|
450
|
+
Root schema types (used in requestBody or responseBody of operations)
|
|
451
|
+
must be defined as object types.
|
|
452
|
+
|
|
453
|
+
This is the rule enforced to ensure consistent API design and to facilitate easier data handling.
|
|
454
|
+
Even though you think that defining a non-object type is more convenient for your specific use case,
|
|
455
|
+
just follow the rule without any resistance.
|
|
456
|
+
|
|
457
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
458
|
+
|
|
459
|
+
If current type is hard to be defined as an object type, just wrap it in an object type like below:
|
|
460
|
+
|
|
461
|
+
\`\`\`typescript
|
|
462
|
+
{
|
|
463
|
+
value: T;
|
|
464
|
+
}
|
|
465
|
+
\`\`\`
|
|
466
|
+
`,
|
|
467
|
+
});
|
|
468
|
+
else if (
|
|
469
|
+
key.endsWith(".IRequest") ||
|
|
470
|
+
key.endsWith(".ISummary") ||
|
|
471
|
+
key.endsWith(".IInvert") ||
|
|
472
|
+
key.endsWith(".ICreate") ||
|
|
473
|
+
key.endsWith(".IUpdate") ||
|
|
474
|
+
key.endsWith(".IJoin") ||
|
|
475
|
+
key.endsWith(".ILogin") ||
|
|
476
|
+
key.endsWith(".IAuthorized")
|
|
477
|
+
)
|
|
478
|
+
props.errors.push({
|
|
479
|
+
path: props.path,
|
|
480
|
+
expected: `AutoBeOpenApi.IJsonSchemaDescriptive.IObject`,
|
|
481
|
+
value: schema,
|
|
482
|
+
description: StringUtil.trim`
|
|
483
|
+
DTO type of .${key.split(".").pop()} suffix must be defined as an object type.
|
|
484
|
+
|
|
485
|
+
This is the rule enforced to ensure consistent API design and to facilitate easier data handling.
|
|
486
|
+
Even though you think that defining a non-object type is more convenient for your specific use case,
|
|
487
|
+
just follow the rule without any resistance.
|
|
488
|
+
|
|
489
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
490
|
+
|
|
491
|
+
If current type is hard to be defined as an object type, just wrap it in an object type like below:
|
|
492
|
+
|
|
493
|
+
\`\`\`typescript
|
|
494
|
+
{
|
|
495
|
+
value: T;
|
|
496
|
+
}
|
|
497
|
+
\`\`\`
|
|
498
|
+
`,
|
|
499
|
+
});
|
|
500
|
+
};
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
const validateReferenceId = (props: {
|
|
504
|
+
errors: IValidation.IError[];
|
|
505
|
+
schema: AutoBeOpenApi.IJsonSchema;
|
|
506
|
+
path: string;
|
|
507
|
+
}): void => {
|
|
508
|
+
if (AutoBeOpenApiTypeChecker.isObject(props.schema) === false) return;
|
|
509
|
+
for (const [key, value] of Object.entries(props.schema.properties)) {
|
|
510
|
+
if (key !== "id" && key.endsWith("_id") === false) continue;
|
|
511
|
+
|
|
512
|
+
const accessor: string = `${props.path}.properties${
|
|
513
|
+
NamingConvention.variable(key) ? `.${key}` : `[${JSON.stringify(key)}]`
|
|
514
|
+
}`;
|
|
515
|
+
const inspect = (schema: AutoBeOpenApi.IJsonSchema): boolean =>
|
|
516
|
+
AutoBeOpenApiTypeChecker.isString(schema) ||
|
|
517
|
+
AutoBeOpenApiTypeChecker.isNull(schema) ||
|
|
518
|
+
(AutoBeOpenApiTypeChecker.isOneOf(schema) &&
|
|
519
|
+
schema.oneOf.every((v) => inspect(v)));
|
|
520
|
+
if (inspect(value) === false)
|
|
521
|
+
props.errors.push({
|
|
522
|
+
path: accessor,
|
|
523
|
+
expected: StringUtil.trim`
|
|
524
|
+
| { type: "string"; format: "uuid"; description: string; }
|
|
525
|
+
| {
|
|
526
|
+
oneOf: [
|
|
527
|
+
{ type: "string"; format: "uuid"; },
|
|
528
|
+
{ type: "null"; },
|
|
529
|
+
];
|
|
530
|
+
description: string;
|
|
531
|
+
}`,
|
|
532
|
+
value,
|
|
533
|
+
description: StringUtil.trim`
|
|
534
|
+
Property names "id" or ending with "_id" must be defined as
|
|
535
|
+
UUID string type, or nullable UUID string type.
|
|
536
|
+
|
|
537
|
+
This is the rule enforced to ensure consistent identification of
|
|
538
|
+
resources across the API. Even though you think that defining a
|
|
539
|
+
different type is more convenient for your specific use case,
|
|
540
|
+
just follow the rule without any resistance.
|
|
541
|
+
|
|
542
|
+
Note that, this is not a recommendation, but an instruction you
|
|
543
|
+
must follow.
|
|
544
|
+
`,
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
const validatePropertyNames = (props: {
|
|
550
|
+
errors: IValidation.IError[];
|
|
551
|
+
schema: AutoBeOpenApi.IJsonSchema;
|
|
552
|
+
path: string;
|
|
553
|
+
}): void => {
|
|
554
|
+
if (AutoBeOpenApiTypeChecker.isObject(props.schema) === false) return;
|
|
555
|
+
for (const key of Object.keys(props.schema.properties)) {
|
|
556
|
+
if (NamingConvention.reserved(key))
|
|
557
|
+
props.errors.push({
|
|
558
|
+
path: `${props.path}.properties${NamingConvention.variable(key) ? `.${key}` : `[${JSON.stringify(key)}]`}`,
|
|
559
|
+
expected: `none system reserved word`,
|
|
560
|
+
value: key,
|
|
561
|
+
description: StringUtil.trim`
|
|
562
|
+
Property name ${JSON.stringify(key)} is a system reserved word.
|
|
563
|
+
|
|
564
|
+
Avoid using system reserved words as property names to prevent
|
|
565
|
+
potential conflicts and ensure clarity in your API design.
|
|
566
|
+
|
|
567
|
+
Change the property name ${JSON.stringify(key)} to a non-reserved
|
|
568
|
+
word at the next time.
|
|
569
|
+
|
|
570
|
+
Note that, this is not a recommendation, but an instruction you
|
|
571
|
+
must follow.
|
|
572
|
+
`,
|
|
573
|
+
});
|
|
574
|
+
else if (NamingConvention.variable(key) === false)
|
|
575
|
+
props.errors.push({
|
|
576
|
+
path: `${props.path}.properties${NamingConvention.variable(key) ? `.${key}` : `[${JSON.stringify(key)}]`}`,
|
|
577
|
+
expected: `valid variable name`,
|
|
578
|
+
value: key,
|
|
579
|
+
description: StringUtil.trim`
|
|
580
|
+
Property name ${JSON.stringify(key)} must be a valid variable name.
|
|
581
|
+
|
|
582
|
+
Valid variable names start with a letter, underscore (_), or dollar sign ($),
|
|
583
|
+
followed by letters, digits, underscores, or dollar signs. They cannot
|
|
584
|
+
contain spaces or special characters.
|
|
585
|
+
|
|
586
|
+
Change the property name ${JSON.stringify(key)} to a valid variable
|
|
587
|
+
name at the next time.
|
|
588
|
+
|
|
589
|
+
Note that, this is not a recommendation, but an instruction you
|
|
590
|
+
must follow.
|
|
591
|
+
`,
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
const validateNumericRanges = (props: IProps): void => {
|
|
597
|
+
AutoBeOpenApiTypeChecker.skim({
|
|
598
|
+
schema: props.schema,
|
|
599
|
+
accessor: `${props.path}[${JSON.stringify(props.typeName)}]`,
|
|
600
|
+
closure: (schema, accessor) => {
|
|
601
|
+
if (
|
|
602
|
+
AutoBeOpenApiTypeChecker.isInteger(schema) === false &&
|
|
603
|
+
AutoBeOpenApiTypeChecker.isNumber(schema) === false
|
|
604
|
+
)
|
|
605
|
+
return;
|
|
606
|
+
|
|
607
|
+
const { minimum, maximum, exclusiveMinimum, exclusiveMaximum } = schema;
|
|
608
|
+
|
|
609
|
+
// Case 1: minimum > maximum
|
|
610
|
+
if (minimum !== undefined && maximum !== undefined && minimum > maximum)
|
|
611
|
+
props.errors.push({
|
|
612
|
+
path: accessor,
|
|
613
|
+
expected: "minimum <= maximum",
|
|
614
|
+
value: schema,
|
|
615
|
+
description: StringUtil.trim`
|
|
616
|
+
Invalid numeric range: minimum (${minimum}) is greater than maximum (${maximum}).
|
|
617
|
+
|
|
618
|
+
This creates an impossible range where no value can satisfy both constraints.
|
|
619
|
+
Either increase maximum or decrease minimum to create a valid range.
|
|
620
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
621
|
+
`,
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
// Case 2: exclusiveMinimum >= exclusiveMaximum
|
|
625
|
+
if (
|
|
626
|
+
exclusiveMinimum !== undefined &&
|
|
627
|
+
exclusiveMaximum !== undefined &&
|
|
628
|
+
exclusiveMinimum >= exclusiveMaximum
|
|
629
|
+
)
|
|
630
|
+
props.errors.push({
|
|
631
|
+
path: accessor,
|
|
632
|
+
expected: "exclusiveMinimum < exclusiveMaximum",
|
|
633
|
+
value: schema,
|
|
634
|
+
description: StringUtil.trim`
|
|
635
|
+
Invalid numeric range: exclusiveMinimum (${exclusiveMinimum}) is greater than
|
|
636
|
+
or equal to exclusiveMaximum (${exclusiveMaximum}).
|
|
637
|
+
|
|
638
|
+
This creates an impossible range where no value can satisfy both constraints.
|
|
639
|
+
Either increase exclusiveMaximum or decrease exclusiveMinimum to create a valid range.
|
|
640
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
641
|
+
`,
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
// Case 3: minimum >= exclusiveMaximum
|
|
645
|
+
if (
|
|
646
|
+
minimum !== undefined &&
|
|
647
|
+
exclusiveMaximum !== undefined &&
|
|
648
|
+
minimum >= exclusiveMaximum
|
|
649
|
+
)
|
|
650
|
+
props.errors.push({
|
|
651
|
+
path: accessor,
|
|
652
|
+
expected: "minimum < exclusiveMaximum",
|
|
653
|
+
value: schema,
|
|
654
|
+
description: StringUtil.trim`
|
|
655
|
+
Invalid numeric range: minimum (${minimum}) is greater than or equal to
|
|
656
|
+
exclusiveMaximum (${exclusiveMaximum}).
|
|
657
|
+
|
|
658
|
+
This creates an impossible range. A value cannot be >= ${minimum} and < ${exclusiveMaximum}
|
|
659
|
+
at the same time when minimum >= exclusiveMaximum.
|
|
660
|
+
Either increase exclusiveMaximum or decrease minimum to create a valid range.
|
|
661
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
662
|
+
`,
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
// Case 4: exclusiveMinimum >= maximum
|
|
666
|
+
if (
|
|
667
|
+
exclusiveMinimum !== undefined &&
|
|
668
|
+
maximum !== undefined &&
|
|
669
|
+
exclusiveMinimum >= maximum
|
|
670
|
+
)
|
|
671
|
+
props.errors.push({
|
|
672
|
+
path: accessor,
|
|
673
|
+
expected: "exclusiveMinimum < maximum",
|
|
674
|
+
value: schema,
|
|
675
|
+
description: StringUtil.trim`
|
|
676
|
+
Invalid numeric range: exclusiveMinimum (${exclusiveMinimum}) is greater than
|
|
677
|
+
or equal to maximum (${maximum}).
|
|
678
|
+
|
|
679
|
+
This creates an impossible range. A value cannot be > ${exclusiveMinimum} and <= ${maximum}
|
|
680
|
+
at the same time when exclusiveMinimum >= maximum.
|
|
681
|
+
Either increase maximum or decrease exclusiveMinimum to create a valid range.
|
|
682
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
683
|
+
`,
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
// Case 5: minimum === maximum with exclusive constraints
|
|
687
|
+
if (
|
|
688
|
+
minimum !== undefined &&
|
|
689
|
+
maximum !== undefined &&
|
|
690
|
+
minimum === maximum &&
|
|
691
|
+
(exclusiveMinimum !== undefined || exclusiveMaximum !== undefined)
|
|
692
|
+
)
|
|
693
|
+
props.errors.push({
|
|
694
|
+
path: accessor,
|
|
695
|
+
expected: "no exclusive constraints when minimum equals maximum",
|
|
696
|
+
value: schema,
|
|
697
|
+
description: StringUtil.trim`
|
|
698
|
+
Invalid numeric range: minimum equals maximum (${minimum}), but exclusive
|
|
699
|
+
constraints are also defined.
|
|
700
|
+
|
|
701
|
+
When minimum === maximum, the only valid value is exactly ${minimum}.
|
|
702
|
+
Adding exclusiveMinimum or exclusiveMaximum makes this impossible.
|
|
703
|
+
Remove the exclusive constraints or adjust minimum/maximum to create a valid range.
|
|
704
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
705
|
+
`,
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
// Case 6: negative multipleOf
|
|
709
|
+
if (schema.multipleOf !== undefined && schema.multipleOf <= 0)
|
|
710
|
+
props.errors.push({
|
|
711
|
+
path: accessor,
|
|
712
|
+
expected: "multipleOf > 0",
|
|
713
|
+
value: schema,
|
|
714
|
+
description: StringUtil.trim`
|
|
715
|
+
Invalid multipleOf value: ${schema.multipleOf}.
|
|
716
|
+
|
|
717
|
+
The multipleOf constraint must be a positive number greater than zero.
|
|
718
|
+
Change multipleOf to a positive value.
|
|
719
|
+
Note that, this is not a recommendation, but an instruction you must follow.
|
|
720
|
+
`,
|
|
721
|
+
});
|
|
722
|
+
},
|
|
723
|
+
});
|
|
724
|
+
};
|
|
725
|
+
}
|