adorn-api 1.0.4 → 1.0.6
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/README.md +766 -51
- package/dist/adapter/express/bootstrap.d.ts +24 -0
- package/dist/adapter/express/bootstrap.d.ts.map +1 -0
- package/dist/adapter/express/index.d.ts +41 -0
- package/dist/adapter/express/index.d.ts.map +1 -0
- package/dist/adapter/express/merge.d.ts +28 -0
- package/dist/adapter/express/merge.d.ts.map +1 -0
- package/dist/cli.cjs +1571 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1552 -2
- package/dist/cli.js.map +1 -1
- package/dist/compiler/analyze/scanControllers.d.ts +35 -0
- package/dist/compiler/analyze/scanControllers.d.ts.map +1 -0
- package/dist/compiler/cache/isStale.d.ts +20 -0
- package/dist/compiler/cache/isStale.d.ts.map +1 -0
- package/dist/compiler/cache/loadArtifacts.d.ts +113 -0
- package/dist/compiler/cache/loadArtifacts.d.ts.map +1 -0
- package/dist/compiler/cache/schema.d.ts +18 -0
- package/dist/compiler/cache/schema.d.ts.map +1 -0
- package/dist/compiler/cache/writeCache.d.ts +8 -0
- package/dist/compiler/cache/writeCache.d.ts.map +1 -0
- package/dist/compiler/manifest/emit.d.ts +7 -0
- package/dist/compiler/manifest/emit.d.ts.map +1 -0
- package/dist/compiler/manifest/format.d.ts +76 -0
- package/dist/compiler/manifest/format.d.ts.map +1 -0
- package/dist/compiler/runner/createProgram.d.ts +8 -0
- package/dist/compiler/runner/createProgram.d.ts.map +1 -0
- package/dist/compiler/schema/extractAnnotations.d.ts +10 -0
- package/dist/compiler/schema/extractAnnotations.d.ts.map +1 -0
- package/dist/compiler/schema/openapi.d.ts +19 -0
- package/dist/compiler/schema/openapi.d.ts.map +1 -0
- package/dist/compiler/schema/typeToJsonSchema.d.ts +49 -0
- package/dist/compiler/schema/typeToJsonSchema.d.ts.map +1 -0
- package/dist/compiler/validation/emitPrecompiledValidators.d.ts +46 -0
- package/dist/compiler/validation/emitPrecompiledValidators.d.ts.map +1 -0
- package/dist/decorators/Auth.d.ts +5 -0
- package/dist/decorators/Auth.d.ts.map +1 -0
- package/dist/decorators/Controller.d.ts +2 -0
- package/dist/decorators/Controller.d.ts.map +1 -0
- package/dist/decorators/Public.d.ts +2 -0
- package/dist/decorators/Public.d.ts.map +1 -0
- package/dist/decorators/Use.d.ts +5 -0
- package/dist/decorators/Use.d.ts.map +1 -0
- package/dist/decorators/index.d.ts +5 -6
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/methods.d.ts +5 -145
- package/dist/decorators/methods.d.ts.map +1 -1
- package/dist/express.cjs +775 -0
- package/dist/express.cjs.map +1 -0
- package/dist/express.d.ts +6 -1
- package/dist/express.d.ts.map +1 -1
- package/dist/express.js +738 -1
- package/dist/express.js.map +1 -1
- package/dist/http.d.ts +29 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/index.cjs +573 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +12 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +490 -26
- package/dist/index.js.map +1 -1
- package/dist/metal/index.cjs +219 -0
- package/dist/metal/index.cjs.map +1 -0
- package/dist/metal/index.d.ts +6 -0
- package/dist/metal/index.d.ts.map +1 -0
- package/dist/metal/index.js +188 -0
- package/dist/metal/index.js.map +1 -0
- package/dist/metal/readMetalBag.d.ts +33 -0
- package/dist/metal/readMetalBag.d.ts.map +1 -0
- package/dist/metal/registerMetalEntities.d.ts +6 -0
- package/dist/metal/registerMetalEntities.d.ts.map +1 -0
- package/dist/metal/schemaFromEntity.d.ts +11 -0
- package/dist/metal/schemaFromEntity.d.ts.map +1 -0
- package/dist/metal/symbolMetadata.d.ts +2 -0
- package/dist/metal/symbolMetadata.d.ts.map +1 -0
- package/dist/runtime/auth/runtime.d.ts +34 -0
- package/dist/runtime/auth/runtime.d.ts.map +1 -0
- package/dist/runtime/metadata/bucket.d.ts +3 -0
- package/dist/runtime/metadata/bucket.d.ts.map +1 -0
- package/dist/runtime/metadata/key.d.ts +2 -0
- package/dist/runtime/metadata/key.d.ts.map +1 -0
- package/dist/runtime/metadata/read.d.ts +3 -0
- package/dist/runtime/metadata/read.d.ts.map +1 -0
- package/dist/runtime/metadata/types.d.ts +21 -0
- package/dist/runtime/metadata/types.d.ts.map +1 -0
- package/dist/runtime/polyfill.d.ts +2 -0
- package/dist/runtime/polyfill.d.ts.map +1 -0
- package/dist/runtime/upload.d.ts +7 -0
- package/dist/runtime/upload.d.ts.map +1 -0
- package/dist/runtime/validation/ajv.d.ts +20 -0
- package/dist/runtime/validation/ajv.d.ts.map +1 -0
- package/dist/runtime/validation/index.d.ts +2 -0
- package/dist/runtime/validation/index.d.ts.map +1 -0
- package/dist/schema/decorators.d.ts +37 -0
- package/dist/schema/decorators.d.ts.map +1 -0
- package/dist/schema/index.cjs +214 -0
- package/dist/schema/index.cjs.map +1 -0
- package/dist/schema/index.d.ts +2 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +163 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/scripts/adorn-example.cjs +148 -0
- package/dist/scripts/adorn-example.cjs.map +1 -0
- package/dist/utils/operationId.d.ts +2 -0
- package/dist/utils/operationId.d.ts.map +1 -0
- package/dist/utils/path.d.ts +2 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/package.json +92 -57
- package/dist/adapters/express/createApp.d.ts +0 -158
- package/dist/adapters/express/createApp.d.ts.map +0 -1
- package/dist/adapters/express/createApp.js +0 -141
- package/dist/adapters/express/createApp.js.map +0 -1
- package/dist/adapters/express/index.d.ts +0 -7
- package/dist/adapters/express/index.d.ts.map +0 -1
- package/dist/adapters/express/index.js +0 -7
- package/dist/adapters/express/index.js.map +0 -1
- package/dist/adapters/express/middleware/errorHandler.d.ts +0 -194
- package/dist/adapters/express/middleware/errorHandler.d.ts.map +0 -1
- package/dist/adapters/express/middleware/errorHandler.js +0 -167
- package/dist/adapters/express/middleware/errorHandler.js.map +0 -1
- package/dist/adapters/express/middleware/requestContext.d.ts +0 -2
- package/dist/adapters/express/middleware/requestContext.d.ts.map +0 -1
- package/dist/adapters/express/middleware/requestContext.js +0 -3
- package/dist/adapters/express/middleware/requestContext.js.map +0 -1
- package/dist/adapters/express/router.d.ts +0 -10
- package/dist/adapters/express/router.d.ts.map +0 -1
- package/dist/adapters/express/router.js +0 -105
- package/dist/adapters/express/router.js.map +0 -1
- package/dist/adapters/express/swagger/index.d.ts +0 -2
- package/dist/adapters/express/swagger/index.d.ts.map +0 -1
- package/dist/adapters/express/swagger/index.js +0 -2
- package/dist/adapters/express/swagger/index.js.map +0 -1
- package/dist/adapters/express/swagger/serve.d.ts +0 -12
- package/dist/adapters/express/swagger/serve.d.ts.map +0 -1
- package/dist/adapters/express/swagger/serve.js +0 -72
- package/dist/adapters/express/swagger/serve.js.map +0 -1
- package/dist/adapters/express/transport/request.d.ts +0 -4
- package/dist/adapters/express/transport/request.d.ts.map +0 -1
- package/dist/adapters/express/transport/request.js +0 -12
- package/dist/adapters/express/transport/request.js.map +0 -1
- package/dist/adapters/express/transport/response.d.ts +0 -5
- package/dist/adapters/express/transport/response.d.ts.map +0 -1
- package/dist/adapters/express/transport/response.js +0 -36
- package/dist/adapters/express/transport/response.js.map +0 -1
- package/dist/cli/commands/dev.d.ts +0 -2
- package/dist/cli/commands/dev.d.ts.map +0 -1
- package/dist/cli/commands/dev.js +0 -3
- package/dist/cli/commands/dev.js.map +0 -1
- package/dist/cli/commands/gen.d.ts +0 -2
- package/dist/cli/commands/gen.d.ts.map +0 -1
- package/dist/cli/commands/gen.js +0 -3
- package/dist/cli/commands/gen.js.map +0 -1
- package/dist/cli/main.d.ts +0 -2
- package/dist/cli/main.d.ts.map +0 -1
- package/dist/cli/main.js +0 -3
- package/dist/cli/main.js.map +0 -1
- package/dist/compiler/config/defaults.d.ts +0 -2
- package/dist/compiler/config/defaults.d.ts.map +0 -1
- package/dist/compiler/config/defaults.js +0 -3
- package/dist/compiler/config/defaults.js.map +0 -1
- package/dist/compiler/config/loadConfig.d.ts +0 -2
- package/dist/compiler/config/loadConfig.d.ts.map +0 -1
- package/dist/compiler/config/loadConfig.js +0 -3
- package/dist/compiler/config/loadConfig.js.map +0 -1
- package/dist/compiler/diagnostics/errors.d.ts +0 -2
- package/dist/compiler/diagnostics/errors.d.ts.map +0 -1
- package/dist/compiler/diagnostics/errors.js +0 -3
- package/dist/compiler/diagnostics/errors.js.map +0 -1
- package/dist/compiler/emit/openapi.d.ts +0 -2
- package/dist/compiler/emit/openapi.d.ts.map +0 -1
- package/dist/compiler/emit/openapi.js +0 -3
- package/dist/compiler/emit/openapi.js.map +0 -1
- package/dist/compiler/emit/routes.d.ts +0 -2
- package/dist/compiler/emit/routes.d.ts.map +0 -1
- package/dist/compiler/emit/routes.js +0 -3
- package/dist/compiler/emit/routes.js.map +0 -1
- package/dist/compiler/program/loadTsProgram.d.ts +0 -2
- package/dist/compiler/program/loadTsProgram.d.ts.map +0 -1
- package/dist/compiler/program/loadTsProgram.js +0 -3
- package/dist/compiler/program/loadTsProgram.js.map +0 -1
- package/dist/compiler/scan/actions.d.ts +0 -2
- package/dist/compiler/scan/actions.d.ts.map +0 -1
- package/dist/compiler/scan/actions.js +0 -3
- package/dist/compiler/scan/actions.js.map +0 -1
- package/dist/compiler/scan/controllers.d.ts +0 -2
- package/dist/compiler/scan/controllers.d.ts.map +0 -1
- package/dist/compiler/scan/controllers.js +0 -3
- package/dist/compiler/scan/controllers.js.map +0 -1
- package/dist/compiler/scan/types.d.ts +0 -2
- package/dist/compiler/scan/types.d.ts.map +0 -1
- package/dist/compiler/scan/types.js +0 -3
- package/dist/compiler/scan/types.js.map +0 -1
- package/dist/contracts/context.d.ts +0 -10
- package/dist/contracts/context.d.ts.map +0 -1
- package/dist/contracts/context.js +0 -2
- package/dist/contracts/context.js.map +0 -1
- package/dist/contracts/errors.d.ts +0 -22
- package/dist/contracts/errors.d.ts.map +0 -1
- package/dist/contracts/errors.js +0 -2
- package/dist/contracts/errors.js.map +0 -1
- package/dist/contracts/http.d.ts +0 -2
- package/dist/contracts/http.d.ts.map +0 -1
- package/dist/contracts/http.js +0 -3
- package/dist/contracts/http.js.map +0 -1
- package/dist/contracts/middleware.d.ts +0 -2
- package/dist/contracts/middleware.d.ts.map +0 -1
- package/dist/contracts/middleware.js +0 -3
- package/dist/contracts/middleware.js.map +0 -1
- package/dist/contracts/openapi-v3.d.ts +0 -538
- package/dist/contracts/openapi-v3.d.ts.map +0 -1
- package/dist/contracts/openapi-v3.js +0 -2
- package/dist/contracts/openapi-v3.js.map +0 -1
- package/dist/contracts/openapi.d.ts +0 -2
- package/dist/contracts/openapi.d.ts.map +0 -1
- package/dist/contracts/openapi.js +0 -2
- package/dist/contracts/openapi.js.map +0 -1
- package/dist/contracts/reply.d.ts +0 -119
- package/dist/contracts/reply.d.ts.map +0 -1
- package/dist/contracts/reply.js +0 -43
- package/dist/contracts/reply.js.map +0 -1
- package/dist/contracts/response-types.d.ts +0 -40
- package/dist/contracts/response-types.d.ts.map +0 -1
- package/dist/contracts/response-types.js +0 -2
- package/dist/contracts/response-types.js.map +0 -1
- package/dist/contracts/responses.d.ts +0 -98
- package/dist/contracts/responses.d.ts.map +0 -1
- package/dist/contracts/responses.js +0 -2
- package/dist/contracts/responses.js.map +0 -1
- package/dist/contracts/route-options.d.ts +0 -155
- package/dist/contracts/route-options.d.ts.map +0 -1
- package/dist/contracts/route-options.js +0 -2
- package/dist/contracts/route-options.js.map +0 -1
- package/dist/contracts/route-typing.d.ts +0 -25
- package/dist/contracts/route-typing.d.ts.map +0 -1
- package/dist/contracts/route-typing.js +0 -2
- package/dist/contracts/route-typing.js.map +0 -1
- package/dist/contracts/validator.d.ts +0 -146
- package/dist/contracts/validator.d.ts.map +0 -1
- package/dist/contracts/validator.js +0 -2
- package/dist/contracts/validator.js.map +0 -1
- package/dist/core/binding/binder.d.ts +0 -74
- package/dist/core/binding/binder.d.ts.map +0 -1
- package/dist/core/binding/binder.js +0 -161
- package/dist/core/binding/binder.js.map +0 -1
- package/dist/core/binding/coerce/arrays.d.ts +0 -7
- package/dist/core/binding/coerce/arrays.d.ts.map +0 -1
- package/dist/core/binding/coerce/arrays.js +0 -28
- package/dist/core/binding/coerce/arrays.js.map +0 -1
- package/dist/core/binding/coerce/csv.d.ts +0 -2
- package/dist/core/binding/coerce/csv.d.ts.map +0 -1
- package/dist/core/binding/coerce/csv.js +0 -7
- package/dist/core/binding/coerce/csv.js.map +0 -1
- package/dist/core/binding/coerce/objects.d.ts +0 -2
- package/dist/core/binding/coerce/objects.d.ts.map +0 -1
- package/dist/core/binding/coerce/objects.js +0 -3
- package/dist/core/binding/coerce/objects.js.map +0 -1
- package/dist/core/binding/coerce/primitives.d.ts +0 -70
- package/dist/core/binding/coerce/primitives.d.ts.map +0 -1
- package/dist/core/binding/coerce/primitives.js +0 -88
- package/dist/core/binding/coerce/primitives.js.map +0 -1
- package/dist/core/binding/index.d.ts +0 -2
- package/dist/core/binding/index.d.ts.map +0 -1
- package/dist/core/binding/index.js +0 -2
- package/dist/core/binding/index.js.map +0 -1
- package/dist/core/binding/rules/inferFromHttpMethod.d.ts +0 -6
- package/dist/core/binding/rules/inferFromHttpMethod.d.ts.map +0 -1
- package/dist/core/binding/rules/inferFromHttpMethod.js +0 -11
- package/dist/core/binding/rules/inferFromHttpMethod.js.map +0 -1
- package/dist/core/binding/rules/inferFromPath.d.ts +0 -2
- package/dist/core/binding/rules/inferFromPath.d.ts.map +0 -1
- package/dist/core/binding/rules/inferFromPath.js +0 -9
- package/dist/core/binding/rules/inferFromPath.js.map +0 -1
- package/dist/core/binding/rules/wrappers.d.ts +0 -2
- package/dist/core/binding/rules/wrappers.d.ts.map +0 -1
- package/dist/core/binding/rules/wrappers.js +0 -3
- package/dist/core/binding/rules/wrappers.js.map +0 -1
- package/dist/core/errors/http-error.d.ts +0 -63
- package/dist/core/errors/http-error.d.ts.map +0 -1
- package/dist/core/errors/http-error.js +0 -71
- package/dist/core/errors/http-error.js.map +0 -1
- package/dist/core/errors/index.d.ts +0 -4
- package/dist/core/errors/index.d.ts.map +0 -1
- package/dist/core/errors/index.js +0 -4
- package/dist/core/errors/index.js.map +0 -1
- package/dist/core/errors/problem.d.ts +0 -3
- package/dist/core/errors/problem.d.ts.map +0 -1
- package/dist/core/errors/problem.js +0 -33
- package/dist/core/errors/problem.js.map +0 -1
- package/dist/core/errors/validation-error.d.ts +0 -73
- package/dist/core/errors/validation-error.d.ts.map +0 -1
- package/dist/core/errors/validation-error.js +0 -82
- package/dist/core/errors/validation-error.js.map +0 -1
- package/dist/core/openapi/buildOpenApi.d.ts +0 -79
- package/dist/core/openapi/buildOpenApi.d.ts.map +0 -1
- package/dist/core/openapi/buildOpenApi.js +0 -196
- package/dist/core/openapi/buildOpenApi.js.map +0 -1
- package/dist/core/openapi/index.d.ts +0 -2
- package/dist/core/openapi/index.d.ts.map +0 -1
- package/dist/core/openapi/index.js +0 -2
- package/dist/core/openapi/index.js.map +0 -1
- package/dist/core/openapi/schema/formats.d.ts +0 -2
- package/dist/core/openapi/schema/formats.d.ts.map +0 -1
- package/dist/core/openapi/schema/formats.js +0 -3
- package/dist/core/openapi/schema/formats.js.map +0 -1
- package/dist/core/openapi/schema/registry.d.ts +0 -9
- package/dist/core/openapi/schema/registry.d.ts.map +0 -1
- package/dist/core/openapi/schema/registry.js +0 -21
- package/dist/core/openapi/schema/registry.js.map +0 -1
- package/dist/core/openapi/schema/schemaModel.d.ts +0 -2
- package/dist/core/openapi/schema/schemaModel.d.ts.map +0 -1
- package/dist/core/openapi/schema/schemaModel.js +0 -3
- package/dist/core/openapi/schema/schemaModel.js.map +0 -1
- package/dist/core/openapi/schema/schemaRegistry.d.ts +0 -2
- package/dist/core/openapi/schema/schemaRegistry.d.ts.map +0 -1
- package/dist/core/openapi/schema/schemaRegistry.js +0 -3
- package/dist/core/openapi/schema/schemaRegistry.js.map +0 -1
- package/dist/core/openapi/schema/toOpenApi.d.ts +0 -4
- package/dist/core/openapi/schema/toOpenApi.d.ts.map +0 -1
- package/dist/core/openapi/schema/toOpenApi.js +0 -82
- package/dist/core/openapi/schema/toOpenApi.js.map +0 -1
- package/dist/core/pipeline/compose.d.ts +0 -2
- package/dist/core/pipeline/compose.d.ts.map +0 -1
- package/dist/core/pipeline/compose.js +0 -3
- package/dist/core/pipeline/compose.js.map +0 -1
- package/dist/core/pipeline/errorMap.d.ts +0 -2
- package/dist/core/pipeline/errorMap.d.ts.map +0 -1
- package/dist/core/pipeline/errorMap.js +0 -3
- package/dist/core/pipeline/errorMap.js.map +0 -1
- package/dist/core/pipeline/invoke.d.ts +0 -2
- package/dist/core/pipeline/invoke.d.ts.map +0 -1
- package/dist/core/pipeline/invoke.js +0 -3
- package/dist/core/pipeline/invoke.js.map +0 -1
- package/dist/core/pipeline/result.d.ts +0 -2
- package/dist/core/pipeline/result.d.ts.map +0 -1
- package/dist/core/pipeline/result.js +0 -3
- package/dist/core/pipeline/result.js.map +0 -1
- package/dist/core/registry/buildRegistry.d.ts +0 -3
- package/dist/core/registry/buildRegistry.d.ts.map +0 -1
- package/dist/core/registry/buildRegistry.js +0 -105
- package/dist/core/registry/buildRegistry.js.map +0 -1
- package/dist/core/registry/conflicts.d.ts +0 -6
- package/dist/core/registry/conflicts.d.ts.map +0 -1
- package/dist/core/registry/conflicts.js +0 -21
- package/dist/core/registry/conflicts.js.map +0 -1
- package/dist/core/registry/index.d.ts +0 -5
- package/dist/core/registry/index.d.ts.map +0 -1
- package/dist/core/registry/index.js +0 -5
- package/dist/core/registry/index.js.map +0 -1
- package/dist/core/registry/normalize.d.ts +0 -3
- package/dist/core/registry/normalize.d.ts.map +0 -1
- package/dist/core/registry/normalize.js +0 -24
- package/dist/core/registry/normalize.js.map +0 -1
- package/dist/core/registry/types.d.ts +0 -225
- package/dist/core/registry/types.d.ts.map +0 -1
- package/dist/core/registry/types.js +0 -2
- package/dist/core/registry/types.js.map +0 -1
- package/dist/core/reply/index.d.ts +0 -3
- package/dist/core/reply/index.d.ts.map +0 -1
- package/dist/core/reply/index.js +0 -3
- package/dist/core/reply/index.js.map +0 -1
- package/dist/core/reply/reply.d.ts +0 -102
- package/dist/core/reply/reply.d.ts.map +0 -1
- package/dist/core/reply/reply.js +0 -105
- package/dist/core/reply/reply.js.map +0 -1
- package/dist/core/reply/typed.d.ts +0 -161
- package/dist/core/reply/typed.d.ts.map +0 -1
- package/dist/core/reply/typed.js +0 -154
- package/dist/core/reply/typed.js.map +0 -1
- package/dist/core/responses/helpers.d.ts +0 -10
- package/dist/core/responses/helpers.d.ts.map +0 -1
- package/dist/core/responses/helpers.js +0 -8
- package/dist/core/responses/helpers.js.map +0 -1
- package/dist/core/responses/index.d.ts +0 -4
- package/dist/core/responses/index.d.ts.map +0 -1
- package/dist/core/responses/index.js +0 -4
- package/dist/core/responses/index.js.map +0 -1
- package/dist/core/responses/normalize.d.ts +0 -3
- package/dist/core/responses/normalize.d.ts.map +0 -1
- package/dist/core/responses/normalize.js +0 -33
- package/dist/core/responses/normalize.js.map +0 -1
- package/dist/core/responses/pickStatus.d.ts +0 -3
- package/dist/core/responses/pickStatus.d.ts.map +0 -1
- package/dist/core/responses/pickStatus.js +0 -27
- package/dist/core/responses/pickStatus.js.map +0 -1
- package/dist/core/route/defineRoute.d.ts +0 -74
- package/dist/core/route/defineRoute.d.ts.map +0 -1
- package/dist/core/route/defineRoute.js +0 -59
- package/dist/core/route/defineRoute.js.map +0 -1
- package/dist/core/route/index.d.ts +0 -2
- package/dist/core/route/index.d.ts.map +0 -1
- package/dist/core/route/index.js +0 -2
- package/dist/core/route/index.js.map +0 -1
- package/dist/core/serialization/json.d.ts +0 -2
- package/dist/core/serialization/json.d.ts.map +0 -1
- package/dist/core/serialization/json.js +0 -3
- package/dist/core/serialization/json.js.map +0 -1
- package/dist/core/typing/path-params.d.ts +0 -2
- package/dist/core/typing/path-params.d.ts.map +0 -1
- package/dist/core/typing/path-params.js +0 -2
- package/dist/core/typing/path-params.js.map +0 -1
- package/dist/decorators/binding.d.ts +0 -9
- package/dist/decorators/binding.d.ts.map +0 -1
- package/dist/decorators/binding.js +0 -18
- package/dist/decorators/binding.js.map +0 -1
- package/dist/decorators/controller.d.ts +0 -6
- package/dist/decorators/controller.d.ts.map +0 -1
- package/dist/decorators/controller.js +0 -26
- package/dist/decorators/controller.js.map +0 -1
- package/dist/decorators/db.d.ts +0 -2
- package/dist/decorators/db.d.ts.map +0 -1
- package/dist/decorators/db.js +0 -3
- package/dist/decorators/db.js.map +0 -1
- package/dist/decorators/docs.d.ts +0 -8
- package/dist/decorators/docs.d.ts.map +0 -1
- package/dist/decorators/docs.js +0 -46
- package/dist/decorators/docs.js.map +0 -1
- package/dist/decorators/index.js +0 -7
- package/dist/decorators/index.js.map +0 -1
- package/dist/decorators/methods.js +0 -170
- package/dist/decorators/methods.js.map +0 -1
- package/dist/decorators/middleware.d.ts +0 -2
- package/dist/decorators/middleware.d.ts.map +0 -1
- package/dist/decorators/middleware.js +0 -3
- package/dist/decorators/middleware.js.map +0 -1
- package/dist/decorators/responses.d.ts +0 -7
- package/dist/decorators/responses.d.ts.map +0 -1
- package/dist/decorators/responses.js +0 -44
- package/dist/decorators/responses.js.map +0 -1
- package/dist/decorators/security.d.ts +0 -8
- package/dist/decorators/security.d.ts.map +0 -1
- package/dist/decorators/security.js +0 -39
- package/dist/decorators/security.js.map +0 -1
- package/dist/integrations/metal-orm/index.d.ts +0 -2
- package/dist/integrations/metal-orm/index.d.ts.map +0 -1
- package/dist/integrations/metal-orm/index.js +0 -2
- package/dist/integrations/metal-orm/index.js.map +0 -1
- package/dist/integrations/metal-orm/pagination/executePaged.d.ts +0 -2
- package/dist/integrations/metal-orm/pagination/executePaged.d.ts.map +0 -1
- package/dist/integrations/metal-orm/pagination/executePaged.js +0 -3
- package/dist/integrations/metal-orm/pagination/executePaged.js.map +0 -1
- package/dist/integrations/metal-orm/pagination/page.d.ts +0 -2
- package/dist/integrations/metal-orm/pagination/page.d.ts.map +0 -1
- package/dist/integrations/metal-orm/pagination/page.js +0 -3
- package/dist/integrations/metal-orm/pagination/page.js.map +0 -1
- package/dist/integrations/metal-orm/query/filters.d.ts +0 -2
- package/dist/integrations/metal-orm/query/filters.d.ts.map +0 -1
- package/dist/integrations/metal-orm/query/filters.js +0 -3
- package/dist/integrations/metal-orm/query/filters.js.map +0 -1
- package/dist/integrations/metal-orm/query/search.d.ts +0 -2
- package/dist/integrations/metal-orm/query/search.d.ts.map +0 -1
- package/dist/integrations/metal-orm/query/search.js +0 -3
- package/dist/integrations/metal-orm/query/search.js.map +0 -1
- package/dist/integrations/metal-orm/query/sort.d.ts +0 -2
- package/dist/integrations/metal-orm/query/sort.d.ts.map +0 -1
- package/dist/integrations/metal-orm/query/sort.js +0 -3
- package/dist/integrations/metal-orm/query/sort.js.map +0 -1
- package/dist/integrations/metal-orm/save-graph/helpers.d.ts +0 -2
- package/dist/integrations/metal-orm/save-graph/helpers.d.ts.map +0 -1
- package/dist/integrations/metal-orm/save-graph/helpers.js +0 -3
- package/dist/integrations/metal-orm/save-graph/helpers.js.map +0 -1
- package/dist/integrations/metal-orm/save-graph/types.d.ts +0 -2
- package/dist/integrations/metal-orm/save-graph/types.d.ts.map +0 -1
- package/dist/integrations/metal-orm/save-graph/types.js +0 -3
- package/dist/integrations/metal-orm/save-graph/types.js.map +0 -1
- package/dist/integrations/metal-orm/schema/column-map.d.ts +0 -96
- package/dist/integrations/metal-orm/schema/column-map.d.ts.map +0 -1
- package/dist/integrations/metal-orm/schema/column-map.js +0 -207
- package/dist/integrations/metal-orm/schema/column-map.js.map +0 -1
- package/dist/integrations/metal-orm/schema/ddl.d.ts +0 -2
- package/dist/integrations/metal-orm/schema/ddl.d.ts.map +0 -1
- package/dist/integrations/metal-orm/schema/ddl.js +0 -3
- package/dist/integrations/metal-orm/schema/ddl.js.map +0 -1
- package/dist/integrations/metal-orm/schema/dto.d.ts +0 -7
- package/dist/integrations/metal-orm/schema/dto.d.ts.map +0 -1
- package/dist/integrations/metal-orm/schema/dto.js +0 -34
- package/dist/integrations/metal-orm/schema/dto.js.map +0 -1
- package/dist/integrations/metal-orm/schema/entity.d.ts +0 -99
- package/dist/integrations/metal-orm/schema/entity.d.ts.map +0 -1
- package/dist/integrations/metal-orm/schema/entity.js +0 -99
- package/dist/integrations/metal-orm/schema/entity.js.map +0 -1
- package/dist/integrations/metal-orm/schema/filters.d.ts +0 -11
- package/dist/integrations/metal-orm/schema/filters.d.ts.map +0 -1
- package/dist/integrations/metal-orm/schema/filters.js +0 -21
- package/dist/integrations/metal-orm/schema/filters.js.map +0 -1
- package/dist/integrations/metal-orm/schema/index.d.ts +0 -5
- package/dist/integrations/metal-orm/schema/index.d.ts.map +0 -1
- package/dist/integrations/metal-orm/schema/index.js +0 -5
- package/dist/integrations/metal-orm/schema/index.js.map +0 -1
- package/dist/integrations/metal-orm/schema/openapi/entityToSchema.d.ts +0 -2
- package/dist/integrations/metal-orm/schema/openapi/entityToSchema.d.ts.map +0 -1
- package/dist/integrations/metal-orm/schema/openapi/entityToSchema.js +0 -3
- package/dist/integrations/metal-orm/schema/openapi/entityToSchema.js.map +0 -1
- package/dist/integrations/metal-orm/schema/openapi/tableDefToSchema.d.ts +0 -2
- package/dist/integrations/metal-orm/schema/openapi/tableDefToSchema.d.ts.map +0 -1
- package/dist/integrations/metal-orm/schema/openapi/tableDefToSchema.js +0 -3
- package/dist/integrations/metal-orm/schema/openapi/tableDefToSchema.js.map +0 -1
- package/dist/integrations/metal-orm/schema/sqlite.d.ts +0 -2
- package/dist/integrations/metal-orm/schema/sqlite.d.ts.map +0 -1
- package/dist/integrations/metal-orm/schema/sqlite.js +0 -3
- package/dist/integrations/metal-orm/schema/sqlite.js.map +0 -1
- package/dist/integrations/metal-orm/schema/tabledef.d.ts +0 -4
- package/dist/integrations/metal-orm/schema/tabledef.d.ts.map +0 -1
- package/dist/integrations/metal-orm/schema/tabledef.js +0 -10
- package/dist/integrations/metal-orm/schema/tabledef.js.map +0 -1
- package/dist/integrations/metal-orm/schema/types.d.ts +0 -7
- package/dist/integrations/metal-orm/schema/types.d.ts.map +0 -1
- package/dist/integrations/metal-orm/schema/types.js +0 -2
- package/dist/integrations/metal-orm/schema/types.js.map +0 -1
- package/dist/integrations/metal-orm/serialization/entitySerializer.d.ts +0 -2
- package/dist/integrations/metal-orm/serialization/entitySerializer.d.ts.map +0 -1
- package/dist/integrations/metal-orm/serialization/entitySerializer.js +0 -3
- package/dist/integrations/metal-orm/serialization/entitySerializer.js.map +0 -1
- package/dist/integrations/metal-orm/serialization/relationPolicy.d.ts +0 -2
- package/dist/integrations/metal-orm/serialization/relationPolicy.d.ts.map +0 -1
- package/dist/integrations/metal-orm/serialization/relationPolicy.js +0 -3
- package/dist/integrations/metal-orm/serialization/relationPolicy.js.map +0 -1
- package/dist/integrations/metal-orm/session/context.d.ts +0 -2
- package/dist/integrations/metal-orm/session/context.d.ts.map +0 -1
- package/dist/integrations/metal-orm/session/context.js +0 -3
- package/dist/integrations/metal-orm/session/context.js.map +0 -1
- package/dist/integrations/metal-orm/session/middleware.d.ts +0 -2
- package/dist/integrations/metal-orm/session/middleware.d.ts.map +0 -1
- package/dist/integrations/metal-orm/session/middleware.js +0 -3
- package/dist/integrations/metal-orm/session/middleware.js.map +0 -1
- package/dist/integrations/metal-orm/session/transaction.d.ts +0 -2
- package/dist/integrations/metal-orm/session/transaction.d.ts.map +0 -1
- package/dist/integrations/metal-orm/session/transaction.js +0 -3
- package/dist/integrations/metal-orm/session/transaction.js.map +0 -1
- package/dist/integrations/metal-orm/testing/setupSchema.d.ts +0 -2
- package/dist/integrations/metal-orm/testing/setupSchema.d.ts.map +0 -1
- package/dist/integrations/metal-orm/testing/setupSchema.js +0 -3
- package/dist/integrations/metal-orm/testing/setupSchema.js.map +0 -1
- package/dist/integrations/metal-orm/testing/sqliteMemory.d.ts +0 -2
- package/dist/integrations/metal-orm/testing/sqliteMemory.d.ts.map +0 -1
- package/dist/integrations/metal-orm/testing/sqliteMemory.js +0 -3
- package/dist/integrations/metal-orm/testing/sqliteMemory.js.map +0 -1
- package/dist/metadata/bag.d.ts +0 -18
- package/dist/metadata/bag.d.ts.map +0 -1
- package/dist/metadata/bag.js +0 -39
- package/dist/metadata/bag.js.map +0 -1
- package/dist/metadata/index.d.ts +0 -4
- package/dist/metadata/index.d.ts.map +0 -1
- package/dist/metadata/index.js +0 -4
- package/dist/metadata/index.js.map +0 -1
- package/dist/metadata/keys.d.ts +0 -254
- package/dist/metadata/keys.d.ts.map +0 -1
- package/dist/metadata/keys.js +0 -23
- package/dist/metadata/keys.js.map +0 -1
- package/dist/metadata/merge.d.ts +0 -9
- package/dist/metadata/merge.d.ts.map +0 -1
- package/dist/metadata/merge.js +0 -30
- package/dist/metadata/merge.js.map +0 -1
- package/dist/metal-orm.d.ts +0 -2
- package/dist/metal-orm.d.ts.map +0 -1
- package/dist/metal-orm.js +0 -2
- package/dist/metal-orm.js.map +0 -1
- package/dist/validation/native/index.d.ts +0 -3
- package/dist/validation/native/index.d.ts.map +0 -1
- package/dist/validation/native/index.js +0 -3
- package/dist/validation/native/index.js.map +0 -1
- package/dist/validation/native/ir.d.ts +0 -38
- package/dist/validation/native/ir.d.ts.map +0 -1
- package/dist/validation/native/ir.js +0 -2
- package/dist/validation/native/ir.js.map +0 -1
- package/dist/validation/native/schema.d.ts +0 -63
- package/dist/validation/native/schema.d.ts.map +0 -1
- package/dist/validation/native/schema.js +0 -271
- package/dist/validation/native/schema.js.map +0 -1
- package/dist/validation/native/validator.d.ts +0 -21
- package/dist/validation/native/validator.d.ts.map +0 -1
- package/dist/validation/native/validator.js +0 -48
- package/dist/validation/native/validator.js.map +0 -1
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,1571 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
// src/cli.ts
|
|
27
|
+
var import_node_fs5 = require("fs");
|
|
28
|
+
var import_node_path5 = require("path");
|
|
29
|
+
|
|
30
|
+
// src/compiler/runner/createProgram.ts
|
|
31
|
+
var import_typescript = __toESM(require("typescript"), 1);
|
|
32
|
+
var import_node_fs = require("fs");
|
|
33
|
+
var import_node_path = require("path");
|
|
34
|
+
function createProgramFromConfig(tsconfigPath) {
|
|
35
|
+
const absolutePath = (0, import_node_path.resolve)(tsconfigPath);
|
|
36
|
+
const configDir = (0, import_node_path.dirname)(absolutePath);
|
|
37
|
+
const configFile = import_typescript.default.readConfigFile(absolutePath, (path4) => (0, import_node_fs.readFileSync)(path4, "utf-8"));
|
|
38
|
+
if (configFile.error) {
|
|
39
|
+
throw new Error(`Failed to read tsconfig: ${import_typescript.default.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`);
|
|
40
|
+
}
|
|
41
|
+
const parsed = import_typescript.default.parseJsonConfigFileContent(configFile.config, import_typescript.default.sys, configDir);
|
|
42
|
+
if (parsed.errors.length > 0) {
|
|
43
|
+
const messages = parsed.errors.map((e) => import_typescript.default.flattenDiagnosticMessageText(e.messageText, "\n"));
|
|
44
|
+
throw new Error(`Failed to parse tsconfig:
|
|
45
|
+
${messages.join("\n")}`);
|
|
46
|
+
}
|
|
47
|
+
const program = import_typescript.default.createProgram(parsed.fileNames, parsed.options);
|
|
48
|
+
const checker = program.getTypeChecker();
|
|
49
|
+
const sourceFiles = program.getSourceFiles().filter(
|
|
50
|
+
(sf) => !sf.isDeclarationFile && !sf.fileName.includes("node_modules")
|
|
51
|
+
);
|
|
52
|
+
return { program, checker, sourceFiles };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/compiler/analyze/scanControllers.ts
|
|
56
|
+
var import_typescript2 = __toESM(require("typescript"), 1);
|
|
57
|
+
|
|
58
|
+
// src/utils/operationId.ts
|
|
59
|
+
function defaultOperationId(controllerName, methodName) {
|
|
60
|
+
return `${controllerName}_${methodName}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/compiler/analyze/scanControllers.ts
|
|
64
|
+
function scanControllers(sourceFiles, checker) {
|
|
65
|
+
const controllers = [];
|
|
66
|
+
for (const sourceFile of sourceFiles) {
|
|
67
|
+
import_typescript2.default.forEachChild(sourceFile, (node) => {
|
|
68
|
+
if (import_typescript2.default.isClassDeclaration(node) && node.name) {
|
|
69
|
+
const controller = analyzeClass(node, sourceFile, checker);
|
|
70
|
+
if (controller) {
|
|
71
|
+
controllers.push(controller);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return controllers;
|
|
77
|
+
}
|
|
78
|
+
function analyzeClass(node, sourceFile, checker) {
|
|
79
|
+
if (!node.name) return null;
|
|
80
|
+
const controllerDecorator = findDecorator(node, "Controller");
|
|
81
|
+
if (!controllerDecorator) return null;
|
|
82
|
+
const basePath = extractDecoratorStringArg(controllerDecorator) ?? "/";
|
|
83
|
+
const className = node.name.text;
|
|
84
|
+
const consumes = extractClassConsumes(node, checker);
|
|
85
|
+
const produces = extractClassProduces(node, checker);
|
|
86
|
+
const operations = [];
|
|
87
|
+
for (const member of node.members) {
|
|
88
|
+
if (import_typescript2.default.isMethodDeclaration(member) && member.name) {
|
|
89
|
+
const operation = analyzeMethod(member, className, checker);
|
|
90
|
+
if (operation) {
|
|
91
|
+
operations.push(operation);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (operations.length === 0) return null;
|
|
96
|
+
return {
|
|
97
|
+
className,
|
|
98
|
+
basePath,
|
|
99
|
+
sourceFile,
|
|
100
|
+
classDeclaration: node,
|
|
101
|
+
operations,
|
|
102
|
+
consumes,
|
|
103
|
+
produces
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function extractClassConsumes(node, checker) {
|
|
107
|
+
const decorator = findDecorator(node, "Consumes");
|
|
108
|
+
if (!decorator) return void 0;
|
|
109
|
+
const callExpr = decorator.expression;
|
|
110
|
+
if (!import_typescript2.default.isCallExpression(callExpr)) return void 0;
|
|
111
|
+
const args = callExpr.arguments;
|
|
112
|
+
if (args.length === 0) return void 0;
|
|
113
|
+
const firstArg = args[0];
|
|
114
|
+
if (import_typescript2.default.isStringLiteral(firstArg)) {
|
|
115
|
+
return [firstArg.text];
|
|
116
|
+
}
|
|
117
|
+
if (import_typescript2.default.isArrayLiteralExpression(firstArg)) {
|
|
118
|
+
return firstArg.elements.filter(import_typescript2.default.isStringLiteral).map((e) => e.text);
|
|
119
|
+
}
|
|
120
|
+
return void 0;
|
|
121
|
+
}
|
|
122
|
+
function extractClassProduces(node, checker) {
|
|
123
|
+
const decorator = findDecorator(node, "Produces");
|
|
124
|
+
if (!decorator) return void 0;
|
|
125
|
+
const callExpr = decorator.expression;
|
|
126
|
+
if (!import_typescript2.default.isCallExpression(callExpr)) return void 0;
|
|
127
|
+
const args = callExpr.arguments;
|
|
128
|
+
if (args.length === 0) return void 0;
|
|
129
|
+
const firstArg = args[0];
|
|
130
|
+
if (import_typescript2.default.isStringLiteral(firstArg)) {
|
|
131
|
+
return [firstArg.text];
|
|
132
|
+
}
|
|
133
|
+
if (import_typescript2.default.isArrayLiteralExpression(firstArg)) {
|
|
134
|
+
return firstArg.elements.filter(import_typescript2.default.isStringLiteral).map((e) => e.text);
|
|
135
|
+
}
|
|
136
|
+
return void 0;
|
|
137
|
+
}
|
|
138
|
+
function analyzeMethod(node, className, checker) {
|
|
139
|
+
const methodName = import_typescript2.default.isIdentifier(node.name) ? node.name.text : null;
|
|
140
|
+
if (!methodName) return null;
|
|
141
|
+
const httpMethods = ["Get", "Post", "Put", "Patch", "Delete"];
|
|
142
|
+
let httpMethod = null;
|
|
143
|
+
let path4 = "/";
|
|
144
|
+
for (const method of httpMethods) {
|
|
145
|
+
const decorator = findDecorator(node, method);
|
|
146
|
+
if (decorator) {
|
|
147
|
+
httpMethod = method.toUpperCase();
|
|
148
|
+
path4 = extractDecoratorStringArg(decorator) ?? "/";
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (!httpMethod) return null;
|
|
153
|
+
const signature = checker.getSignatureFromDeclaration(node);
|
|
154
|
+
if (!signature) return null;
|
|
155
|
+
let returnType = checker.getReturnTypeOfSignature(signature);
|
|
156
|
+
returnType = unwrapPromise(returnType, checker);
|
|
157
|
+
const parameters = [];
|
|
158
|
+
for (let i = 0; i < node.parameters.length; i++) {
|
|
159
|
+
const param = node.parameters[i];
|
|
160
|
+
const paramName = import_typescript2.default.isIdentifier(param.name) ? param.name.text : `arg${i}`;
|
|
161
|
+
const paramType = checker.getTypeAtLocation(param);
|
|
162
|
+
const isOptional = !!param.questionToken || !!param.initializer;
|
|
163
|
+
parameters.push({
|
|
164
|
+
name: paramName,
|
|
165
|
+
index: i,
|
|
166
|
+
type: paramType,
|
|
167
|
+
isOptional,
|
|
168
|
+
paramNode: param
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
const pathParamNames = extractPathParams(path4);
|
|
172
|
+
const pathParamIndices = matchPathParamsToIndices(pathParamNames, parameters);
|
|
173
|
+
const { bodyParamIndex, queryParamIndices, queryObjectParamIndex, headerObjectParamIndex, cookieObjectParamIndex, bodyContentType } = classifyParameters(parameters, httpMethod, pathParamIndices, checker);
|
|
174
|
+
return {
|
|
175
|
+
methodName,
|
|
176
|
+
httpMethod,
|
|
177
|
+
path: path4,
|
|
178
|
+
operationId: defaultOperationId(className, methodName),
|
|
179
|
+
methodDeclaration: node,
|
|
180
|
+
returnType,
|
|
181
|
+
parameters,
|
|
182
|
+
pathParamIndices,
|
|
183
|
+
bodyParamIndex,
|
|
184
|
+
queryParamIndices,
|
|
185
|
+
queryObjectParamIndex,
|
|
186
|
+
headerObjectParamIndex,
|
|
187
|
+
cookieObjectParamIndex,
|
|
188
|
+
bodyContentType
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function extractPathParams(path4) {
|
|
192
|
+
const matches = path4.match(/:([^/]+)/g);
|
|
193
|
+
if (!matches) return [];
|
|
194
|
+
return matches.map((m) => m.slice(1));
|
|
195
|
+
}
|
|
196
|
+
function matchPathParamsToIndices(pathParamNames, parameters) {
|
|
197
|
+
const indices = [];
|
|
198
|
+
for (const name of pathParamNames) {
|
|
199
|
+
const param = parameters.find((p) => p.name === name);
|
|
200
|
+
if (param) {
|
|
201
|
+
indices.push(param.index);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return indices;
|
|
205
|
+
}
|
|
206
|
+
function classifyParameters(parameters, httpMethod, pathParamIndices, checker) {
|
|
207
|
+
const usedIndices = new Set(pathParamIndices);
|
|
208
|
+
const queryParamIndices = [];
|
|
209
|
+
let bodyParamIndex = null;
|
|
210
|
+
let queryObjectParamIndex = null;
|
|
211
|
+
let headerObjectParamIndex = null;
|
|
212
|
+
let cookieObjectParamIndex = null;
|
|
213
|
+
const isBodyMethod = ["POST", "PUT", "PATCH"].includes(httpMethod);
|
|
214
|
+
for (let i = 0; i < parameters.length; i++) {
|
|
215
|
+
const param = parameters[i];
|
|
216
|
+
if (usedIndices.has(i)) continue;
|
|
217
|
+
const typeStr = param.type.getSymbol()?.getName() ?? "";
|
|
218
|
+
if (typeStr === "Body") {
|
|
219
|
+
bodyParamIndex = i;
|
|
220
|
+
usedIndices.add(i);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (typeStr === "Query") {
|
|
224
|
+
queryObjectParamIndex = i;
|
|
225
|
+
usedIndices.add(i);
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
if (typeStr === "Headers") {
|
|
229
|
+
headerObjectParamIndex = i;
|
|
230
|
+
usedIndices.add(i);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (typeStr === "Cookies") {
|
|
234
|
+
cookieObjectParamIndex = i;
|
|
235
|
+
usedIndices.add(i);
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
if (isBodyMethod && bodyParamIndex === null) {
|
|
239
|
+
bodyParamIndex = i;
|
|
240
|
+
usedIndices.add(i);
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
const isObj = isObjectType(param.type, checker);
|
|
244
|
+
if (isObj && queryObjectParamIndex === null && !isBodyMethod) {
|
|
245
|
+
queryObjectParamIndex = i;
|
|
246
|
+
usedIndices.add(i);
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
queryParamIndices.push(i);
|
|
250
|
+
usedIndices.add(i);
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
bodyParamIndex,
|
|
254
|
+
queryParamIndices,
|
|
255
|
+
queryObjectParamIndex,
|
|
256
|
+
headerObjectParamIndex,
|
|
257
|
+
cookieObjectParamIndex,
|
|
258
|
+
bodyContentType: void 0
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function isObjectType(type, checker) {
|
|
262
|
+
const objectFlags = (type.flags & import_typescript2.default.TypeFlags.Object) !== 0;
|
|
263
|
+
if (!objectFlags) return false;
|
|
264
|
+
const symbol = type.getSymbol();
|
|
265
|
+
if (symbol?.getName() === "__object") return true;
|
|
266
|
+
const properties = checker.getPropertiesOfType(type);
|
|
267
|
+
if (properties.length > 0) return true;
|
|
268
|
+
const callSignatures = type.getCallSignatures();
|
|
269
|
+
if (callSignatures && callSignatures.length > 0) return false;
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
function findDecorator(node, name) {
|
|
273
|
+
const decorators = import_typescript2.default.getDecorators(node);
|
|
274
|
+
if (!decorators) return null;
|
|
275
|
+
for (const decorator of decorators) {
|
|
276
|
+
if (import_typescript2.default.isCallExpression(decorator.expression)) {
|
|
277
|
+
const expr = decorator.expression.expression;
|
|
278
|
+
if (import_typescript2.default.isIdentifier(expr) && expr.text === name) {
|
|
279
|
+
return decorator;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
function extractDecoratorStringArg(decorator) {
|
|
286
|
+
if (import_typescript2.default.isCallExpression(decorator.expression)) {
|
|
287
|
+
const arg = decorator.expression.arguments[0];
|
|
288
|
+
if (arg && import_typescript2.default.isStringLiteral(arg)) {
|
|
289
|
+
return arg.text;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
function unwrapPromise(type, checker) {
|
|
295
|
+
const symbol = type.getSymbol();
|
|
296
|
+
if (symbol?.getName() === "Promise") {
|
|
297
|
+
const typeArgs = type.typeArguments;
|
|
298
|
+
if (typeArgs && typeArgs.length > 0) {
|
|
299
|
+
return typeArgs[0];
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return type;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// src/compiler/schema/openapi.ts
|
|
306
|
+
var import_typescript5 = __toESM(require("typescript"), 1);
|
|
307
|
+
|
|
308
|
+
// src/compiler/schema/typeToJsonSchema.ts
|
|
309
|
+
var import_typescript3 = __toESM(require("typescript"), 1);
|
|
310
|
+
function typeToJsonSchema(type, ctx, typeNode) {
|
|
311
|
+
const { checker } = ctx;
|
|
312
|
+
if (type.flags & import_typescript3.default.TypeFlags.Undefined) {
|
|
313
|
+
return {};
|
|
314
|
+
}
|
|
315
|
+
if (type.flags & import_typescript3.default.TypeFlags.Null) {
|
|
316
|
+
return { type: "null" };
|
|
317
|
+
}
|
|
318
|
+
if (type.flags & import_typescript3.default.TypeFlags.String) {
|
|
319
|
+
return { type: "string" };
|
|
320
|
+
}
|
|
321
|
+
if (type.flags & import_typescript3.default.TypeFlags.Number) {
|
|
322
|
+
return { type: "number" };
|
|
323
|
+
}
|
|
324
|
+
if (type.flags & import_typescript3.default.TypeFlags.Boolean) {
|
|
325
|
+
return { type: "boolean" };
|
|
326
|
+
}
|
|
327
|
+
if (type.flags & import_typescript3.default.TypeFlags.BigInt) {
|
|
328
|
+
return {
|
|
329
|
+
type: "string",
|
|
330
|
+
format: "int64",
|
|
331
|
+
pattern: "^-?\\d+$"
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
if (type.flags & import_typescript3.default.TypeFlags.StringLiteral) {
|
|
335
|
+
const value = type.value;
|
|
336
|
+
return { type: "string", enum: [value] };
|
|
337
|
+
}
|
|
338
|
+
if (type.flags & import_typescript3.default.TypeFlags.NumberLiteral) {
|
|
339
|
+
const value = type.value;
|
|
340
|
+
return { type: "number", enum: [value] };
|
|
341
|
+
}
|
|
342
|
+
if (type.flags & import_typescript3.default.TypeFlags.BooleanLiteral) {
|
|
343
|
+
const intrinsic = type.intrinsicName;
|
|
344
|
+
return { type: "boolean", enum: [intrinsic === "true"] };
|
|
345
|
+
}
|
|
346
|
+
if (type.isUnion()) {
|
|
347
|
+
return handleUnion(type.types, ctx, typeNode);
|
|
348
|
+
}
|
|
349
|
+
if (type.isIntersection()) {
|
|
350
|
+
return handleIntersection(type.types, ctx, typeNode);
|
|
351
|
+
}
|
|
352
|
+
if (checker.isArrayType(type)) {
|
|
353
|
+
const typeArgs = type.typeArguments;
|
|
354
|
+
const itemType = typeArgs?.[0];
|
|
355
|
+
const items = itemType ? typeToJsonSchema(itemType, ctx) : {};
|
|
356
|
+
return {
|
|
357
|
+
type: "array",
|
|
358
|
+
items,
|
|
359
|
+
uniqueItems: isSetType(type, checker) ? true : void 0
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
if (type.flags & import_typescript3.default.TypeFlags.Object) {
|
|
363
|
+
return handleObjectType(type, ctx, typeNode);
|
|
364
|
+
}
|
|
365
|
+
return {};
|
|
366
|
+
}
|
|
367
|
+
function isSetType(type, checker) {
|
|
368
|
+
const symbol = type.getSymbol();
|
|
369
|
+
if (!symbol) return false;
|
|
370
|
+
const name = symbol.getName();
|
|
371
|
+
if (name === "Set") return true;
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
function handleUnion(types, ctx, typeNode) {
|
|
375
|
+
const nullType = types.find((t) => t.flags & import_typescript3.default.TypeFlags.Null);
|
|
376
|
+
const otherTypes = types.filter((t) => !(t.flags & import_typescript3.default.TypeFlags.Null) && !(t.flags & import_typescript3.default.TypeFlags.Undefined));
|
|
377
|
+
const allStringLiterals = otherTypes.every((t) => t.flags & import_typescript3.default.TypeFlags.StringLiteral);
|
|
378
|
+
if (allStringLiterals && otherTypes.length > 0) {
|
|
379
|
+
const enumValues = otherTypes.map((t) => t.value);
|
|
380
|
+
const schema = { type: "string", enum: enumValues };
|
|
381
|
+
if (nullType) {
|
|
382
|
+
schema.type = ["string", "null"];
|
|
383
|
+
}
|
|
384
|
+
return schema;
|
|
385
|
+
}
|
|
386
|
+
if (otherTypes.length === 1 && nullType) {
|
|
387
|
+
const innerSchema = typeToJsonSchema(otherTypes[0], ctx);
|
|
388
|
+
if (typeof innerSchema.type === "string") {
|
|
389
|
+
innerSchema.type = [innerSchema.type, "null"];
|
|
390
|
+
}
|
|
391
|
+
return innerSchema;
|
|
392
|
+
}
|
|
393
|
+
if (otherTypes.length > 1) {
|
|
394
|
+
const branches = otherTypes.map((t) => typeToJsonSchema(t, ctx));
|
|
395
|
+
const hasNull = !!nullType;
|
|
396
|
+
const result = {};
|
|
397
|
+
if (hasNull) {
|
|
398
|
+
result.anyOf = [...branches, { type: "null" }];
|
|
399
|
+
} else {
|
|
400
|
+
result.anyOf = branches;
|
|
401
|
+
}
|
|
402
|
+
const discriminatorResult = detectDiscriminatedUnion(otherTypes, ctx, branches);
|
|
403
|
+
if (discriminatorResult) {
|
|
404
|
+
result.oneOf = branches;
|
|
405
|
+
result.discriminator = discriminatorResult;
|
|
406
|
+
}
|
|
407
|
+
return result;
|
|
408
|
+
}
|
|
409
|
+
if (otherTypes.length === 1) {
|
|
410
|
+
return typeToJsonSchema(otherTypes[0], ctx);
|
|
411
|
+
}
|
|
412
|
+
return {};
|
|
413
|
+
}
|
|
414
|
+
function handleIntersection(types, ctx, typeNode) {
|
|
415
|
+
const brandCollapsed = tryCollapseBrandedIntersection(types, ctx, typeNode);
|
|
416
|
+
if (brandCollapsed) {
|
|
417
|
+
return brandCollapsed;
|
|
418
|
+
}
|
|
419
|
+
const allOf = [];
|
|
420
|
+
for (const t of types) {
|
|
421
|
+
allOf.push(typeToJsonSchema(t, ctx));
|
|
422
|
+
}
|
|
423
|
+
return { allOf };
|
|
424
|
+
}
|
|
425
|
+
function tryCollapseBrandedIntersection(types, ctx, typeNode) {
|
|
426
|
+
const { checker } = ctx;
|
|
427
|
+
const parts = [...types];
|
|
428
|
+
const prim = parts.find(isPrimitiveLike);
|
|
429
|
+
if (!prim) return null;
|
|
430
|
+
const rest = parts.filter((p) => p !== prim);
|
|
431
|
+
if (rest.every((r) => isBrandObject(checker, r, ctx))) {
|
|
432
|
+
return typeToJsonSchema(prim, ctx);
|
|
433
|
+
}
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
function isPrimitiveLike(t) {
|
|
437
|
+
return (t.flags & (import_typescript3.default.TypeFlags.String | import_typescript3.default.TypeFlags.Number | import_typescript3.default.TypeFlags.Boolean | import_typescript3.default.TypeFlags.BigInt)) !== 0 || (t.flags & import_typescript3.default.TypeFlags.StringLiteral) !== 0 || (t.flags & import_typescript3.default.TypeFlags.NumberLiteral) !== 0;
|
|
438
|
+
}
|
|
439
|
+
function isBrandObject(checker, t, ctx) {
|
|
440
|
+
if (!(t.flags & import_typescript3.default.TypeFlags.Object)) return false;
|
|
441
|
+
const props = t.getProperties();
|
|
442
|
+
if (props.length === 0) return false;
|
|
443
|
+
const allowed = /* @__PURE__ */ new Set(["__brand", "__type", "__tag", "brand"]);
|
|
444
|
+
for (const p of props) {
|
|
445
|
+
if (!allowed.has(p.getName())) return false;
|
|
446
|
+
}
|
|
447
|
+
const callSigs = t.getCallSignatures?.();
|
|
448
|
+
if (callSigs && callSigs.length > 0) return false;
|
|
449
|
+
const constructSigs = t.getConstructSignatures?.();
|
|
450
|
+
if (constructSigs && constructSigs.length > 0) return false;
|
|
451
|
+
return true;
|
|
452
|
+
}
|
|
453
|
+
function detectDiscriminatedUnion(types, ctx, branches) {
|
|
454
|
+
if (types.length < 2) return null;
|
|
455
|
+
const candidates = findCommonPropertyNames(ctx.checker, types);
|
|
456
|
+
for (const propName of candidates) {
|
|
457
|
+
const requiredInAll = types.every((t) => isRequiredProperty(ctx.checker, t, propName));
|
|
458
|
+
if (!requiredInAll) continue;
|
|
459
|
+
const literalSets = types.map((t) => getPropertyLiteralValues(ctx.checker, t, propName));
|
|
460
|
+
if (literalSets.some((s) => s === null)) continue;
|
|
461
|
+
const allSets = literalSets;
|
|
462
|
+
if (!areSetsDisjoint(allSets)) continue;
|
|
463
|
+
const mapping = {};
|
|
464
|
+
for (let i = 0; i < types.length; i++) {
|
|
465
|
+
const branchName = getBranchSchemaName(types[i], ctx);
|
|
466
|
+
for (const val of allSets[i]) {
|
|
467
|
+
mapping[val] = `#/components/schemas/${branchName}`;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return { propertyName: propName, mapping };
|
|
471
|
+
}
|
|
472
|
+
return null;
|
|
473
|
+
}
|
|
474
|
+
function findCommonPropertyNames(checker, types) {
|
|
475
|
+
if (types.length === 0) return [];
|
|
476
|
+
const firstProps = types[0].getProperties().map((s) => s.getName());
|
|
477
|
+
return firstProps.filter(
|
|
478
|
+
(name) => types.every((m) => !!checker.getPropertyOfType(m, name))
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
function isRequiredProperty(checker, type, propName) {
|
|
482
|
+
const sym = checker.getPropertyOfType(type, propName);
|
|
483
|
+
if (!sym) return false;
|
|
484
|
+
if (sym.flags & import_typescript3.default.SymbolFlags.Optional) return false;
|
|
485
|
+
const propType = checker.getTypeOfSymbol(sym);
|
|
486
|
+
if (propType.isUnion?.()) {
|
|
487
|
+
const hasUndefined = propType.types.some((t) => (t.flags & import_typescript3.default.TypeFlags.Undefined) !== 0);
|
|
488
|
+
if (hasUndefined) return false;
|
|
489
|
+
}
|
|
490
|
+
return true;
|
|
491
|
+
}
|
|
492
|
+
function getPropertyLiteralValues(checker, type, propName) {
|
|
493
|
+
const sym = checker.getPropertyOfType(type, propName);
|
|
494
|
+
if (!sym) return null;
|
|
495
|
+
const propType = checker.getTypeOfSymbol(sym);
|
|
496
|
+
if (propType.isStringLiteral?.()) {
|
|
497
|
+
return /* @__PURE__ */ new Set([propType.value]);
|
|
498
|
+
}
|
|
499
|
+
if (propType.isUnion?.()) {
|
|
500
|
+
const values = /* @__PURE__ */ new Set();
|
|
501
|
+
for (const m of propType.types) {
|
|
502
|
+
if (!m.isStringLiteral?.()) return null;
|
|
503
|
+
values.add(m.value);
|
|
504
|
+
}
|
|
505
|
+
return values;
|
|
506
|
+
}
|
|
507
|
+
return null;
|
|
508
|
+
}
|
|
509
|
+
function areSetsDisjoint(sets) {
|
|
510
|
+
const seen = /* @__PURE__ */ new Set();
|
|
511
|
+
for (const s of sets) {
|
|
512
|
+
for (const v of s) {
|
|
513
|
+
if (seen.has(v)) return false;
|
|
514
|
+
seen.add(v);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return true;
|
|
518
|
+
}
|
|
519
|
+
function getBranchSchemaName(type, ctx) {
|
|
520
|
+
const symbol = type.getSymbol();
|
|
521
|
+
if (symbol) {
|
|
522
|
+
return symbol.getName();
|
|
523
|
+
}
|
|
524
|
+
const aliasSymbol = type.aliasSymbol;
|
|
525
|
+
if (aliasSymbol) {
|
|
526
|
+
return aliasSymbol.getName();
|
|
527
|
+
}
|
|
528
|
+
return `Anonymous_${ctx.typeNameStack.length}`;
|
|
529
|
+
}
|
|
530
|
+
function handleObjectType(type, ctx, typeNode) {
|
|
531
|
+
const { checker, components, typeStack } = ctx;
|
|
532
|
+
const symbol = type.getSymbol();
|
|
533
|
+
const typeName = symbol?.getName?.() ?? getTypeNameFromNode(typeNode, ctx);
|
|
534
|
+
if (typeName && typeName !== "__type") {
|
|
535
|
+
if (components.has(typeName)) {
|
|
536
|
+
return { $ref: `#/components/schemas/${typeName}` };
|
|
537
|
+
}
|
|
538
|
+
if (typeStack.has(type)) {
|
|
539
|
+
return { $ref: `#/components/schemas/${typeName}` };
|
|
540
|
+
}
|
|
541
|
+
typeStack.add(type);
|
|
542
|
+
}
|
|
543
|
+
const schema = buildObjectSchema(type, ctx, typeNode);
|
|
544
|
+
if (typeName && typeName !== "__type") {
|
|
545
|
+
typeStack.delete(type);
|
|
546
|
+
if (!components.has(typeName)) {
|
|
547
|
+
components.set(typeName, schema);
|
|
548
|
+
}
|
|
549
|
+
return { $ref: `#/components/schemas/${typeName}` };
|
|
550
|
+
}
|
|
551
|
+
typeStack.delete(type);
|
|
552
|
+
return schema;
|
|
553
|
+
}
|
|
554
|
+
function getTypeNameFromNode(typeNode, ctx) {
|
|
555
|
+
if (!typeNode) return `Anonymous_${ctx.typeNameStack.length}`;
|
|
556
|
+
if (import_typescript3.default.isTypeReferenceNode(typeNode)) {
|
|
557
|
+
if (import_typescript3.default.isIdentifier(typeNode.typeName)) {
|
|
558
|
+
return typeNode.typeName.text;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
if (import_typescript3.default.isTypeAliasDeclaration(typeNode.parent)) {
|
|
562
|
+
if (import_typescript3.default.isIdentifier(typeNode.parent.name)) {
|
|
563
|
+
return typeNode.parent.name.text;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
return `Anonymous_${ctx.typeNameStack.length}`;
|
|
567
|
+
}
|
|
568
|
+
function buildObjectSchema(type, ctx, typeNode) {
|
|
569
|
+
const { checker } = ctx;
|
|
570
|
+
const properties = {};
|
|
571
|
+
const required = [];
|
|
572
|
+
const props = checker.getPropertiesOfType(type);
|
|
573
|
+
for (const prop of props) {
|
|
574
|
+
const propName = prop.getName();
|
|
575
|
+
const propType = checker.getTypeOfSymbol(prop);
|
|
576
|
+
const isOptional = !!(prop.flags & import_typescript3.default.SymbolFlags.Optional);
|
|
577
|
+
properties[propName] = typeToJsonSchema(propType, ctx);
|
|
578
|
+
if (!isOptional) {
|
|
579
|
+
required.push(propName);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
const schema = {
|
|
583
|
+
type: "object",
|
|
584
|
+
properties
|
|
585
|
+
};
|
|
586
|
+
if (required.length > 0) {
|
|
587
|
+
schema.required = required;
|
|
588
|
+
}
|
|
589
|
+
if (isRecordType(type, checker)) {
|
|
590
|
+
const valueType = getRecordValueType(type, checker);
|
|
591
|
+
if (valueType) {
|
|
592
|
+
schema.additionalProperties = typeToJsonSchema(valueType, ctx);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return schema;
|
|
596
|
+
}
|
|
597
|
+
function isRecordType(type, checker) {
|
|
598
|
+
const symbol = type.getSymbol();
|
|
599
|
+
if (!symbol) return false;
|
|
600
|
+
const name = symbol.getName();
|
|
601
|
+
if (name === "Record") return true;
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
604
|
+
function getRecordValueType(type, checker) {
|
|
605
|
+
const symbol = type.getSymbol();
|
|
606
|
+
if (!symbol) return null;
|
|
607
|
+
const name = symbol.getName();
|
|
608
|
+
if (name === "Record") {
|
|
609
|
+
const typeRef = type;
|
|
610
|
+
const typeArgs = typeRef.typeArguments;
|
|
611
|
+
if (typeArgs && typeArgs.length >= 2) {
|
|
612
|
+
return typeArgs[1];
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
return null;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// src/compiler/schema/extractAnnotations.ts
|
|
619
|
+
var import_typescript4 = __toESM(require("typescript"), 1);
|
|
620
|
+
function extractPropertySchemaFragments(checker, prop) {
|
|
621
|
+
if (!import_typescript4.default.canHaveDecorators(prop)) return [];
|
|
622
|
+
const decs = import_typescript4.default.getDecorators(prop);
|
|
623
|
+
if (!decs || decs.length === 0) return [];
|
|
624
|
+
const frags = [];
|
|
625
|
+
for (const d of decs) {
|
|
626
|
+
const expr = d.expression;
|
|
627
|
+
let callee;
|
|
628
|
+
let args;
|
|
629
|
+
if (import_typescript4.default.isCallExpression(expr)) {
|
|
630
|
+
callee = expr.expression;
|
|
631
|
+
args = expr.arguments;
|
|
632
|
+
} else {
|
|
633
|
+
callee = expr;
|
|
634
|
+
args = import_typescript4.default.factory.createNodeArray([]);
|
|
635
|
+
}
|
|
636
|
+
const sym = checker.getSymbolAtLocation(callee);
|
|
637
|
+
if (!sym) continue;
|
|
638
|
+
const resolved = resolveImportedDecorator(checker, sym);
|
|
639
|
+
if (!resolved || resolved.module !== "adorn-api/schema") continue;
|
|
640
|
+
const name = resolved.name;
|
|
641
|
+
if (name === "Schema") {
|
|
642
|
+
const obj = args[0];
|
|
643
|
+
if (obj && import_typescript4.default.isObjectLiteralExpression(obj)) {
|
|
644
|
+
const frag = objectLiteralToJson(obj);
|
|
645
|
+
if (frag) frags.push(frag);
|
|
646
|
+
}
|
|
647
|
+
continue;
|
|
648
|
+
}
|
|
649
|
+
if (name === "Min" && isNumberLiteral(args[0])) {
|
|
650
|
+
frags.push({ minimum: Number(args[0].text) });
|
|
651
|
+
} else if (name === "Max" && isNumberLiteral(args[0])) {
|
|
652
|
+
frags.push({ maximum: Number(args[0].text) });
|
|
653
|
+
} else if (name === "ExclusiveMin" && isNumberLiteral(args[0])) {
|
|
654
|
+
frags.push({ exclusiveMinimum: Number(args[0].text) });
|
|
655
|
+
} else if (name === "ExclusiveMax" && isNumberLiteral(args[0])) {
|
|
656
|
+
frags.push({ exclusiveMaximum: Number(args[0].text) });
|
|
657
|
+
} else if (name === "MinLength" && isNumberLiteral(args[0])) {
|
|
658
|
+
frags.push({ minLength: Number(args[0].text) });
|
|
659
|
+
} else if (name === "MaxLength" && isNumberLiteral(args[0])) {
|
|
660
|
+
frags.push({ maxLength: Number(args[0].text) });
|
|
661
|
+
} else if (name === "Format" && isStringLiteral(args[0])) {
|
|
662
|
+
frags.push({ format: args[0].text });
|
|
663
|
+
} else if (name === "Pattern") {
|
|
664
|
+
const arg = args[0];
|
|
665
|
+
if (arg && import_typescript4.default.isRegularExpressionLiteral(arg)) {
|
|
666
|
+
frags.push({ pattern: extractRegexPattern(arg.text) });
|
|
667
|
+
} else if (isStringLiteral(arg)) {
|
|
668
|
+
frags.push({ pattern: arg.text });
|
|
669
|
+
}
|
|
670
|
+
} else if (name === "MinItems" && isNumberLiteral(args[0])) {
|
|
671
|
+
frags.push({ minItems: Number(args[0].text) });
|
|
672
|
+
} else if (name === "MaxItems" && isNumberLiteral(args[0])) {
|
|
673
|
+
frags.push({ maxItems: Number(args[0].text) });
|
|
674
|
+
} else if (name === "MinProperties" && isNumberLiteral(args[0])) {
|
|
675
|
+
frags.push({ minProperties: Number(args[0].text) });
|
|
676
|
+
} else if (name === "MaxProperties" && isNumberLiteral(args[0])) {
|
|
677
|
+
frags.push({ maxProperties: Number(args[0].text) });
|
|
678
|
+
} else if (name === "MultipleOf" && isNumberLiteral(args[0])) {
|
|
679
|
+
frags.push({ multipleOf: Number(args[0].text) });
|
|
680
|
+
} else if (name === "Example") {
|
|
681
|
+
frags.push({ example: literalToJson(args[0]) });
|
|
682
|
+
} else if (name === "Examples" && import_typescript4.default.isArrayLiteralExpression(args[0])) {
|
|
683
|
+
frags.push({ examples: args[0].elements.map((e) => literalToJson(e)) });
|
|
684
|
+
} else if (name === "Description" && isStringLiteral(args[0])) {
|
|
685
|
+
frags.push({ description: args[0].text });
|
|
686
|
+
} else if (name === "Enum" && import_typescript4.default.isArrayLiteralExpression(args[0])) {
|
|
687
|
+
frags.push({ enum: args[0].elements.map((e) => literalToJson(e)) });
|
|
688
|
+
} else if (name === "Const") {
|
|
689
|
+
frags.push({ const: literalToJson(args[0]) });
|
|
690
|
+
} else if (name === "Default") {
|
|
691
|
+
frags.push({ default: literalToJson(args[0]) });
|
|
692
|
+
} else if (name === "AdditionalProperties") {
|
|
693
|
+
const arg = args[0];
|
|
694
|
+
if (arg && (arg.kind === import_typescript4.default.SyntaxKind.FalseKeyword || arg.kind === import_typescript4.default.SyntaxKind.TrueKeyword)) {
|
|
695
|
+
frags.push({ additionalProperties: arg.kind === import_typescript4.default.SyntaxKind.TrueKeyword });
|
|
696
|
+
} else if (arg && import_typescript4.default.isObjectLiteralExpression(arg)) {
|
|
697
|
+
const obj = objectLiteralToJson(arg);
|
|
698
|
+
if (obj) frags.push({ additionalProperties: obj });
|
|
699
|
+
}
|
|
700
|
+
} else if (name === "Closed") {
|
|
701
|
+
frags.push({ additionalProperties: false });
|
|
702
|
+
} else if (name === "ClosedUnevaluated") {
|
|
703
|
+
frags.push({ unevaluatedProperties: false });
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
return frags;
|
|
707
|
+
}
|
|
708
|
+
function resolveImportedDecorator(checker, sym) {
|
|
709
|
+
const target = sym.flags & import_typescript4.default.SymbolFlags.Alias ? checker.getAliasedSymbol(sym) : sym;
|
|
710
|
+
const name = target.getName();
|
|
711
|
+
const decl = target.declarations?.[0];
|
|
712
|
+
if (!decl) return null;
|
|
713
|
+
const fileName = decl.getSourceFile().fileName.replace(/\\/g, "/");
|
|
714
|
+
if (fileName.includes("/node_modules/adorn-api/") || fileName.includes("/src/schema/")) {
|
|
715
|
+
return { module: "adorn-api/schema", name };
|
|
716
|
+
}
|
|
717
|
+
return null;
|
|
718
|
+
}
|
|
719
|
+
function isNumberLiteral(node) {
|
|
720
|
+
return !!node && import_typescript4.default.isNumericLiteral(node);
|
|
721
|
+
}
|
|
722
|
+
function isStringLiteral(node) {
|
|
723
|
+
return !!node && import_typescript4.default.isStringLiteral(node);
|
|
724
|
+
}
|
|
725
|
+
function extractRegexPattern(text) {
|
|
726
|
+
const match = text.match(/^\/(.+)\/[gimsuy]*$/);
|
|
727
|
+
return match ? match[1] : text;
|
|
728
|
+
}
|
|
729
|
+
function objectLiteralToJson(obj) {
|
|
730
|
+
const out = {};
|
|
731
|
+
for (const prop of obj.properties) {
|
|
732
|
+
if (!import_typescript4.default.isPropertyAssignment(prop)) continue;
|
|
733
|
+
const name = prop.name;
|
|
734
|
+
let key;
|
|
735
|
+
if (import_typescript4.default.isIdentifier(name)) {
|
|
736
|
+
key = name.text;
|
|
737
|
+
} else if (import_typescript4.default.isStringLiteral(name)) {
|
|
738
|
+
key = name.text;
|
|
739
|
+
} else {
|
|
740
|
+
continue;
|
|
741
|
+
}
|
|
742
|
+
out[key] = literalToJson(prop.initializer);
|
|
743
|
+
}
|
|
744
|
+
return out;
|
|
745
|
+
}
|
|
746
|
+
function literalToJson(node) {
|
|
747
|
+
if (import_typescript4.default.isStringLiteral(node)) return node.text;
|
|
748
|
+
if (import_typescript4.default.isNumericLiteral(node)) return Number(node.text);
|
|
749
|
+
if (node.kind === import_typescript4.default.SyntaxKind.TrueKeyword) return true;
|
|
750
|
+
if (node.kind === import_typescript4.default.SyntaxKind.FalseKeyword) return false;
|
|
751
|
+
if (node.kind === import_typescript4.default.SyntaxKind.NullKeyword) return null;
|
|
752
|
+
if (import_typescript4.default.isObjectLiteralExpression(node)) return objectLiteralToJson(node);
|
|
753
|
+
if (import_typescript4.default.isArrayLiteralExpression(node)) return node.elements.map((e) => literalToJson(e));
|
|
754
|
+
return void 0;
|
|
755
|
+
}
|
|
756
|
+
function mergeFragments(base, ...frags) {
|
|
757
|
+
const result = { ...base };
|
|
758
|
+
for (const frag of frags) {
|
|
759
|
+
Object.assign(result, frag);
|
|
760
|
+
}
|
|
761
|
+
return result;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
// src/compiler/schema/openapi.ts
|
|
765
|
+
function generateOpenAPI(controllers, checker, options = {}) {
|
|
766
|
+
const components = /* @__PURE__ */ new Map();
|
|
767
|
+
const ctx = {
|
|
768
|
+
checker,
|
|
769
|
+
components,
|
|
770
|
+
typeStack: /* @__PURE__ */ new Set(),
|
|
771
|
+
typeNameStack: []
|
|
772
|
+
};
|
|
773
|
+
const paths = {};
|
|
774
|
+
for (const controller of controllers) {
|
|
775
|
+
for (const operation of controller.operations) {
|
|
776
|
+
const fullPath = convertToOpenApiPath(controller.basePath, operation.path);
|
|
777
|
+
if (!paths[fullPath]) {
|
|
778
|
+
paths[fullPath] = {};
|
|
779
|
+
}
|
|
780
|
+
const method = operation.httpMethod.toLowerCase();
|
|
781
|
+
paths[fullPath][method] = buildOperation(operation, ctx, controller.consumes);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
return {
|
|
785
|
+
openapi: "3.1.0",
|
|
786
|
+
info: {
|
|
787
|
+
title: options.title ?? "API",
|
|
788
|
+
version: options.version ?? "1.0.0"
|
|
789
|
+
},
|
|
790
|
+
components: {
|
|
791
|
+
schemas: Object.fromEntries(components)
|
|
792
|
+
},
|
|
793
|
+
paths
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
function convertToOpenApiPath(basePath, path4) {
|
|
797
|
+
const base = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath;
|
|
798
|
+
const converted = path4.replace(/:([^/]+)/g, "{$1}");
|
|
799
|
+
return base + converted || "/";
|
|
800
|
+
}
|
|
801
|
+
function buildOperation(operation, ctx, controllerConsumes) {
|
|
802
|
+
const op = {
|
|
803
|
+
operationId: operation.operationId,
|
|
804
|
+
responses: {}
|
|
805
|
+
};
|
|
806
|
+
const parameters = [];
|
|
807
|
+
buildPathParameters(operation, ctx, parameters);
|
|
808
|
+
buildQueryParameters(operation, ctx, parameters);
|
|
809
|
+
buildHeaderParameters(operation, ctx, parameters);
|
|
810
|
+
buildCookieParameters(operation, ctx, parameters);
|
|
811
|
+
if (parameters.length > 0) {
|
|
812
|
+
op.parameters = parameters;
|
|
813
|
+
}
|
|
814
|
+
const responseSchema = typeToJsonSchema(operation.returnType, ctx);
|
|
815
|
+
const status = operation.httpMethod === "POST" ? 201 : 200;
|
|
816
|
+
op.responses[status] = {
|
|
817
|
+
description: status === 201 ? "Created" : "OK",
|
|
818
|
+
content: {
|
|
819
|
+
"application/json": {
|
|
820
|
+
schema: responseSchema
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
if (["POST", "PUT", "PATCH"].includes(operation.httpMethod) && operation.bodyParamIndex !== null) {
|
|
825
|
+
const bodyParam = operation.parameters[operation.bodyParamIndex];
|
|
826
|
+
if (bodyParam) {
|
|
827
|
+
let bodySchema = typeToJsonSchema(bodyParam.type, ctx);
|
|
828
|
+
bodySchema = mergeBodySchemaAnnotations(bodyParam, ctx, bodySchema);
|
|
829
|
+
const contentType = operation.bodyContentType ?? controllerConsumes?.[0] ?? "application/json";
|
|
830
|
+
const requestBody = {
|
|
831
|
+
required: !bodyParam.isOptional,
|
|
832
|
+
content: {}
|
|
833
|
+
};
|
|
834
|
+
if (contentType === "multipart/form-data") {
|
|
835
|
+
requestBody.content["multipart/form-data"] = {
|
|
836
|
+
schema: bodySchema
|
|
837
|
+
};
|
|
838
|
+
} else {
|
|
839
|
+
requestBody.content[contentType] = {
|
|
840
|
+
schema: bodySchema
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
op.requestBody = requestBody;
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
return op;
|
|
847
|
+
}
|
|
848
|
+
function mergeBodySchemaAnnotations(bodyParam, ctx, schema) {
|
|
849
|
+
if (!schema.properties) return schema;
|
|
850
|
+
const typeSymbol = bodyParam.type.getSymbol();
|
|
851
|
+
if (!typeSymbol) return schema;
|
|
852
|
+
const declarations = typeSymbol.getDeclarations();
|
|
853
|
+
if (!declarations || declarations.length === 0) return schema;
|
|
854
|
+
const classDecl = declarations[0];
|
|
855
|
+
if (!import_typescript5.default.isClassDeclaration(classDecl)) return schema;
|
|
856
|
+
const result = { ...schema };
|
|
857
|
+
const props = { ...result.properties };
|
|
858
|
+
for (const member of classDecl.members) {
|
|
859
|
+
if (!import_typescript5.default.isPropertyDeclaration(member) || !member.name) continue;
|
|
860
|
+
const propName = import_typescript5.default.isIdentifier(member.name) ? member.name.text : null;
|
|
861
|
+
if (!propName) continue;
|
|
862
|
+
if (!props[propName]) continue;
|
|
863
|
+
const frags = extractPropertySchemaFragments(ctx.checker, member);
|
|
864
|
+
if (frags.length > 0) {
|
|
865
|
+
props[propName] = mergeFragments(props[propName], ...frags);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
result.properties = props;
|
|
869
|
+
return result;
|
|
870
|
+
}
|
|
871
|
+
function buildPathParameters(operation, ctx, parameters) {
|
|
872
|
+
for (const paramIndex of operation.pathParamIndices) {
|
|
873
|
+
const param = operation.parameters[paramIndex];
|
|
874
|
+
if (param) {
|
|
875
|
+
let paramSchema = typeToJsonSchema(param.type, ctx);
|
|
876
|
+
if (param.paramNode) {
|
|
877
|
+
const frags = extractPropertySchemaFragments(ctx.checker, param.paramNode);
|
|
878
|
+
if (frags.length > 0) {
|
|
879
|
+
paramSchema = mergeFragments(paramSchema, ...frags);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
parameters.push({
|
|
883
|
+
name: param.name,
|
|
884
|
+
in: "path",
|
|
885
|
+
required: !param.isOptional,
|
|
886
|
+
schema: paramSchema.$ref ? { type: "string", $ref: paramSchema.$ref } : paramSchema
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
function buildQueryParameters(operation, ctx, parameters) {
|
|
892
|
+
if (operation.queryObjectParamIndex !== null) {
|
|
893
|
+
const queryParam = operation.parameters[operation.queryObjectParamIndex];
|
|
894
|
+
if (!queryParam) return;
|
|
895
|
+
const querySchema = typeToJsonSchema(queryParam.type, ctx);
|
|
896
|
+
if (!querySchema.properties) return;
|
|
897
|
+
const queryObjProps = querySchema.properties;
|
|
898
|
+
for (const [propName, propSchema] of Object.entries(queryObjProps)) {
|
|
899
|
+
const isRequired = querySchema.required?.includes(propName) ?? false;
|
|
900
|
+
const serialization = determineQuerySerialization(propSchema.type);
|
|
901
|
+
parameters.push({
|
|
902
|
+
name: propName,
|
|
903
|
+
in: "query",
|
|
904
|
+
required: isRequired,
|
|
905
|
+
schema: propSchema,
|
|
906
|
+
...Object.keys(serialization).length > 0 ? serialization : {}
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
for (const paramIndex of operation.queryParamIndices) {
|
|
911
|
+
const param = operation.parameters[paramIndex];
|
|
912
|
+
if (param) {
|
|
913
|
+
let paramSchema = typeToJsonSchema(param.type, ctx);
|
|
914
|
+
if (param.paramNode) {
|
|
915
|
+
const frags = extractPropertySchemaFragments(ctx.checker, param.paramNode);
|
|
916
|
+
if (frags.length > 0) {
|
|
917
|
+
paramSchema = mergeFragments(paramSchema, ...frags);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
const serialization = determineQuerySerialization(paramSchema.type);
|
|
921
|
+
parameters.push({
|
|
922
|
+
name: param.name,
|
|
923
|
+
in: "query",
|
|
924
|
+
required: !param.isOptional,
|
|
925
|
+
schema: paramSchema.$ref ? { type: "string", $ref: paramSchema.$ref } : paramSchema,
|
|
926
|
+
...Object.keys(serialization).length > 0 ? serialization : {}
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
function determineQuerySerialization(schemaType) {
|
|
932
|
+
const typeArray = Array.isArray(schemaType) ? schemaType : schemaType ? [schemaType] : [];
|
|
933
|
+
const isArray = typeArray.includes("array");
|
|
934
|
+
if (isArray) {
|
|
935
|
+
return { style: "form", explode: true };
|
|
936
|
+
}
|
|
937
|
+
return {};
|
|
938
|
+
}
|
|
939
|
+
function buildHeaderParameters(operation, ctx, parameters) {
|
|
940
|
+
if (operation.headerObjectParamIndex === null) return;
|
|
941
|
+
const headerParam = operation.parameters[operation.headerObjectParamIndex];
|
|
942
|
+
if (!headerParam) return;
|
|
943
|
+
const headerSchema = typeToJsonSchema(headerParam.type, ctx);
|
|
944
|
+
if (!headerSchema.properties) return;
|
|
945
|
+
const headerObjProps = headerSchema.properties;
|
|
946
|
+
for (const [propName, propSchema] of Object.entries(headerObjProps)) {
|
|
947
|
+
const isRequired = headerSchema.required?.includes(propName) ?? false;
|
|
948
|
+
parameters.push({
|
|
949
|
+
name: propName,
|
|
950
|
+
in: "header",
|
|
951
|
+
required: isRequired,
|
|
952
|
+
schema: propSchema
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
function buildCookieParameters(operation, ctx, parameters) {
|
|
957
|
+
if (operation.cookieObjectParamIndex === null) return;
|
|
958
|
+
const cookieParam = operation.parameters[operation.cookieObjectParamIndex];
|
|
959
|
+
if (!cookieParam) return;
|
|
960
|
+
const cookieSchema = typeToJsonSchema(cookieParam.type, ctx);
|
|
961
|
+
if (!cookieSchema.properties) return;
|
|
962
|
+
const cookieObjProps = cookieSchema.properties;
|
|
963
|
+
for (const [propName, propSchema] of Object.entries(cookieObjProps)) {
|
|
964
|
+
const isRequired = cookieSchema.required?.includes(propName) ?? false;
|
|
965
|
+
parameters.push({
|
|
966
|
+
name: propName,
|
|
967
|
+
in: "cookie",
|
|
968
|
+
required: isRequired,
|
|
969
|
+
schema: propSchema,
|
|
970
|
+
style: "form",
|
|
971
|
+
explode: true
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
// src/compiler/manifest/emit.ts
|
|
977
|
+
var import_typescript6 = __toESM(require("typescript"), 1);
|
|
978
|
+
function generateManifest(controllers, checker, version, validationMode = "ajv-runtime") {
|
|
979
|
+
const components = /* @__PURE__ */ new Map();
|
|
980
|
+
const ctx = {
|
|
981
|
+
checker,
|
|
982
|
+
components,
|
|
983
|
+
typeStack: /* @__PURE__ */ new Set(),
|
|
984
|
+
typeNameStack: []
|
|
985
|
+
};
|
|
986
|
+
const controllerEntries = controllers.map((ctrl) => ({
|
|
987
|
+
controllerId: ctrl.className,
|
|
988
|
+
basePath: ctrl.basePath,
|
|
989
|
+
operations: ctrl.operations.map((op) => buildOperationEntry(op, ctx))
|
|
990
|
+
}));
|
|
991
|
+
const validationConfig = validationMode === "precompiled" ? { mode: "precompiled", precompiledModule: null } : validationMode === "none" ? { mode: "none", precompiledModule: null } : { mode: "ajv-runtime", precompiledModule: null };
|
|
992
|
+
return {
|
|
993
|
+
manifestVersion: 1,
|
|
994
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
995
|
+
generator: {
|
|
996
|
+
name: "adorn-api",
|
|
997
|
+
version,
|
|
998
|
+
typescript: import_typescript6.default.version
|
|
999
|
+
},
|
|
1000
|
+
schemas: {
|
|
1001
|
+
kind: "openapi-3.1",
|
|
1002
|
+
file: "./openapi.json",
|
|
1003
|
+
componentsSchemasPointer: "/components/schemas"
|
|
1004
|
+
},
|
|
1005
|
+
validation: validationConfig,
|
|
1006
|
+
controllers: controllerEntries
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
function buildOperationEntry(op, ctx) {
|
|
1010
|
+
const args = {
|
|
1011
|
+
body: null,
|
|
1012
|
+
path: [],
|
|
1013
|
+
query: [],
|
|
1014
|
+
headers: [],
|
|
1015
|
+
cookies: []
|
|
1016
|
+
};
|
|
1017
|
+
buildPathArgs(op, ctx, args);
|
|
1018
|
+
buildQueryArgs(op, ctx, args);
|
|
1019
|
+
buildHeaderArgs(op, ctx, args);
|
|
1020
|
+
buildCookieArgs(op, ctx, args);
|
|
1021
|
+
if (op.bodyParamIndex !== null) {
|
|
1022
|
+
const bodyParam = op.parameters[op.bodyParamIndex];
|
|
1023
|
+
if (bodyParam) {
|
|
1024
|
+
const bodySchema = typeToJsonSchema(bodyParam.type, ctx);
|
|
1025
|
+
const schemaRef2 = bodySchema.$ref ?? "#/components/schemas/InlineBody";
|
|
1026
|
+
args.body = {
|
|
1027
|
+
index: bodyParam.index,
|
|
1028
|
+
required: !bodyParam.isOptional,
|
|
1029
|
+
contentType: op.bodyContentType ?? "application/json",
|
|
1030
|
+
schemaRef: schemaRef2
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
const responseSchema = typeToJsonSchema(op.returnType, ctx);
|
|
1035
|
+
const status = op.httpMethod === "POST" ? 201 : 200;
|
|
1036
|
+
let schemaRef = responseSchema.$ref;
|
|
1037
|
+
let isArray = false;
|
|
1038
|
+
if (!schemaRef && responseSchema.type === "array" && responseSchema.items?.$ref) {
|
|
1039
|
+
schemaRef = responseSchema.items.$ref;
|
|
1040
|
+
isArray = true;
|
|
1041
|
+
} else if (!schemaRef) {
|
|
1042
|
+
schemaRef = "#/components/schemas/InlineResponse";
|
|
1043
|
+
}
|
|
1044
|
+
return {
|
|
1045
|
+
operationId: op.operationId,
|
|
1046
|
+
http: {
|
|
1047
|
+
method: op.httpMethod,
|
|
1048
|
+
path: op.path
|
|
1049
|
+
},
|
|
1050
|
+
handler: {
|
|
1051
|
+
methodName: op.methodName
|
|
1052
|
+
},
|
|
1053
|
+
args,
|
|
1054
|
+
responses: [
|
|
1055
|
+
{
|
|
1056
|
+
status,
|
|
1057
|
+
contentType: "application/json",
|
|
1058
|
+
schemaRef,
|
|
1059
|
+
isArray
|
|
1060
|
+
}
|
|
1061
|
+
]
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
function buildPathArgs(op, ctx, args) {
|
|
1065
|
+
for (const paramIndex of op.pathParamIndices) {
|
|
1066
|
+
const param = op.parameters[paramIndex];
|
|
1067
|
+
if (param) {
|
|
1068
|
+
const paramSchema = typeToJsonSchema(param.type, ctx);
|
|
1069
|
+
args.path.push({
|
|
1070
|
+
name: param.name,
|
|
1071
|
+
index: param.index,
|
|
1072
|
+
required: !param.isOptional,
|
|
1073
|
+
schemaRef: paramSchema.$ref ?? "#/components/schemas/InlinePathParam",
|
|
1074
|
+
schemaType: paramSchema.type
|
|
1075
|
+
});
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
function buildQueryArgs(op, ctx, args) {
|
|
1080
|
+
if (op.queryObjectParamIndex !== null) {
|
|
1081
|
+
const queryParam = op.parameters[op.queryObjectParamIndex];
|
|
1082
|
+
if (queryParam) {
|
|
1083
|
+
const querySchema = typeToJsonSchema(queryParam.type, ctx);
|
|
1084
|
+
if (!querySchema.properties) return;
|
|
1085
|
+
for (const [propName, propSchema] of Object.entries(querySchema.properties)) {
|
|
1086
|
+
const isRequired = querySchema.required?.includes(propName) ?? false;
|
|
1087
|
+
let schemaRef = propSchema.$ref;
|
|
1088
|
+
if (!schemaRef) {
|
|
1089
|
+
schemaRef = "#/components/schemas/InlineQueryParam";
|
|
1090
|
+
}
|
|
1091
|
+
args.query.push({
|
|
1092
|
+
name: propName,
|
|
1093
|
+
index: queryParam.index,
|
|
1094
|
+
required: !isRequired,
|
|
1095
|
+
schemaRef,
|
|
1096
|
+
schemaType: propSchema.type
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
for (const paramIndex of op.queryParamIndices) {
|
|
1102
|
+
const param = op.parameters[paramIndex];
|
|
1103
|
+
if (param) {
|
|
1104
|
+
const paramSchema = typeToJsonSchema(param.type, ctx);
|
|
1105
|
+
const schemaRef = paramSchema.$ref ?? "#/components/schemas/InlineQueryParam";
|
|
1106
|
+
args.query.push({
|
|
1107
|
+
name: param.name,
|
|
1108
|
+
index: param.index,
|
|
1109
|
+
required: !param.isOptional,
|
|
1110
|
+
schemaRef,
|
|
1111
|
+
schemaType: paramSchema.type
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
function buildHeaderArgs(op, ctx, args) {
|
|
1117
|
+
if (op.headerObjectParamIndex === null) return;
|
|
1118
|
+
const headerParam = op.parameters[op.headerObjectParamIndex];
|
|
1119
|
+
if (!headerParam) return;
|
|
1120
|
+
const headerSchema = typeToJsonSchema(headerParam.type, ctx);
|
|
1121
|
+
if (!headerSchema.properties) return;
|
|
1122
|
+
for (const [propName, propSchema] of Object.entries(headerSchema.properties)) {
|
|
1123
|
+
const isRequired = headerSchema.required?.includes(propName) ?? false;
|
|
1124
|
+
let schemaRef = propSchema.$ref;
|
|
1125
|
+
if (!schemaRef) {
|
|
1126
|
+
schemaRef = "#/components/schemas/InlineHeaderParam";
|
|
1127
|
+
}
|
|
1128
|
+
args.headers.push({
|
|
1129
|
+
name: propName,
|
|
1130
|
+
index: headerParam.index,
|
|
1131
|
+
required: !isRequired,
|
|
1132
|
+
schemaRef,
|
|
1133
|
+
schemaType: propSchema.type
|
|
1134
|
+
});
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
function buildCookieArgs(op, ctx, args) {
|
|
1138
|
+
if (op.cookieObjectParamIndex === null) return;
|
|
1139
|
+
const cookieParam = op.parameters[op.cookieObjectParamIndex];
|
|
1140
|
+
if (!cookieParam) return;
|
|
1141
|
+
const cookieSchema = typeToJsonSchema(cookieParam.type, ctx);
|
|
1142
|
+
if (!cookieSchema.properties) return;
|
|
1143
|
+
for (const [propName, propSchema] of Object.entries(cookieSchema.properties)) {
|
|
1144
|
+
const isRequired = cookieSchema.required?.includes(propName) ?? false;
|
|
1145
|
+
let schemaRef = propSchema.$ref;
|
|
1146
|
+
if (!schemaRef) {
|
|
1147
|
+
schemaRef = "#/components/schemas/InlineCookieParam";
|
|
1148
|
+
}
|
|
1149
|
+
args.cookies.push({
|
|
1150
|
+
name: propName,
|
|
1151
|
+
index: cookieParam.index,
|
|
1152
|
+
required: !isRequired,
|
|
1153
|
+
schemaRef,
|
|
1154
|
+
schemaType: propSchema.type,
|
|
1155
|
+
serialization: { style: "form", explode: true }
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// src/compiler/validation/emitPrecompiledValidators.ts
|
|
1161
|
+
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
1162
|
+
var import_node_path2 = __toESM(require("path"), 1);
|
|
1163
|
+
var import_node_crypto = __toESM(require("crypto"), 1);
|
|
1164
|
+
var import_ajv = __toESM(require("ajv"), 1);
|
|
1165
|
+
var import_ajv_formats = __toESM(require("ajv-formats"), 1);
|
|
1166
|
+
var OAS_SCHEMA_ONLY = /* @__PURE__ */ new Set(["discriminator", "xml", "externalDocs", "example"]);
|
|
1167
|
+
function sanitizeSchemaForAjv(schema) {
|
|
1168
|
+
if (schema == null || typeof schema !== "object") return schema;
|
|
1169
|
+
if (Array.isArray(schema)) return schema.map(sanitizeSchemaForAjv);
|
|
1170
|
+
const out = {};
|
|
1171
|
+
for (const [k, v] of Object.entries(schema)) {
|
|
1172
|
+
if (OAS_SCHEMA_ONLY.has(k)) continue;
|
|
1173
|
+
if (k.startsWith("x-")) continue;
|
|
1174
|
+
out[k] = sanitizeSchemaForAjv(v);
|
|
1175
|
+
}
|
|
1176
|
+
return out;
|
|
1177
|
+
}
|
|
1178
|
+
function rewriteComponentRefs(schema) {
|
|
1179
|
+
if (schema == null || typeof schema !== "object") return schema;
|
|
1180
|
+
if (Array.isArray(schema)) return schema.map(rewriteComponentRefs);
|
|
1181
|
+
if (typeof schema.$ref === "string") {
|
|
1182
|
+
const ref = schema.$ref;
|
|
1183
|
+
const m = ref.match(/^#\/components\/schemas\/(.+)$/);
|
|
1184
|
+
if (m) {
|
|
1185
|
+
return { ...schema, $ref: m[1] };
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
const out = {};
|
|
1189
|
+
for (const [k, v] of Object.entries(schema)) {
|
|
1190
|
+
out[k] = rewriteComponentRefs(v);
|
|
1191
|
+
}
|
|
1192
|
+
return out;
|
|
1193
|
+
}
|
|
1194
|
+
function safeId(s) {
|
|
1195
|
+
return s.replace(/[^A-Za-z0-9_]/g, "_").replace(/^[^A-Za-z_]/, "_$&");
|
|
1196
|
+
}
|
|
1197
|
+
function schemaNameFromRef(schemaRef) {
|
|
1198
|
+
return schemaRef.replace(/^#\/components\/schemas\//, "");
|
|
1199
|
+
}
|
|
1200
|
+
async function emitPrecompiledValidators(opts) {
|
|
1201
|
+
const outDir = opts.outDir;
|
|
1202
|
+
const cjsPath = import_node_path2.default.join(outDir, "validators.cjs");
|
|
1203
|
+
const esmPath = import_node_path2.default.join(outDir, "validators.mjs");
|
|
1204
|
+
const metaPath = import_node_path2.default.join(outDir, "validators.meta.json");
|
|
1205
|
+
import_node_fs2.default.mkdirSync(outDir, { recursive: true });
|
|
1206
|
+
const schemas = [];
|
|
1207
|
+
for (const [name, sch] of Object.entries(opts.openapi.components?.schemas ?? {})) {
|
|
1208
|
+
const clean = rewriteComponentRefs(sanitizeSchemaForAjv(sch));
|
|
1209
|
+
schemas.push({ ...clean, $id: name });
|
|
1210
|
+
}
|
|
1211
|
+
const opIndex = {};
|
|
1212
|
+
for (const ctrl of opts.manifest.controllers ?? []) {
|
|
1213
|
+
for (const op of ctrl.operations ?? []) {
|
|
1214
|
+
const entry = { response: {} };
|
|
1215
|
+
opIndex[op.operationId] = entry;
|
|
1216
|
+
if (op.args.body?.schemaRef) {
|
|
1217
|
+
const typeName = schemaNameFromRef(op.args.body.schemaRef);
|
|
1218
|
+
const id = safeId(`op_${op.operationId}_body`);
|
|
1219
|
+
schemas.push({ $id: id, $ref: typeName });
|
|
1220
|
+
entry.body = id;
|
|
1221
|
+
}
|
|
1222
|
+
for (const r of op.responses ?? []) {
|
|
1223
|
+
if (!r.schemaRef) continue;
|
|
1224
|
+
const typeName = schemaNameFromRef(r.schemaRef);
|
|
1225
|
+
const key = `${r.status}|${r.contentType}`;
|
|
1226
|
+
const id = safeId(`op_${op.operationId}_res_${r.status}_${r.contentType}`);
|
|
1227
|
+
schemas.push({ $id: id, $ref: typeName });
|
|
1228
|
+
entry.response[key] = id;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
const strictOpt = opts.strict === "off" ? false : opts.strict === "log" ? "log" : true;
|
|
1233
|
+
const ajv = new import_ajv.default.default({
|
|
1234
|
+
schemas,
|
|
1235
|
+
allErrors: true,
|
|
1236
|
+
strict: strictOpt,
|
|
1237
|
+
code: { source: true }
|
|
1238
|
+
});
|
|
1239
|
+
import_ajv_formats.default.default(ajv, { mode: opts.formatsMode ?? "full" });
|
|
1240
|
+
let cjs;
|
|
1241
|
+
const standaloneModule = require("ajv/dist/standalone");
|
|
1242
|
+
if (typeof standaloneModule === "function") {
|
|
1243
|
+
cjs = standaloneModule(ajv);
|
|
1244
|
+
} else if (standaloneModule && typeof standaloneModule.default === "function") {
|
|
1245
|
+
cjs = standaloneModule.default(ajv);
|
|
1246
|
+
} else {
|
|
1247
|
+
throw new Error("Unable to find standalone code generator in ajv/dist/standalone");
|
|
1248
|
+
}
|
|
1249
|
+
cjs += "\n\n// --- adorn-api operation lookup (generated) ---\n";
|
|
1250
|
+
cjs += "exports.validators = {\n";
|
|
1251
|
+
for (const [operationId, v] of Object.entries(opIndex)) {
|
|
1252
|
+
cjs += ` ${JSON.stringify(operationId)}: {
|
|
1253
|
+
`;
|
|
1254
|
+
cjs += ` body: ${v.body ? `exports[${JSON.stringify(v.body)}]` : "undefined"},
|
|
1255
|
+
`;
|
|
1256
|
+
cjs += ` response: {
|
|
1257
|
+
`;
|
|
1258
|
+
for (const [key, id] of Object.entries(v.response)) {
|
|
1259
|
+
cjs += ` ${JSON.stringify(key)}: exports[${JSON.stringify(id)}],
|
|
1260
|
+
`;
|
|
1261
|
+
}
|
|
1262
|
+
cjs += ` }
|
|
1263
|
+
`;
|
|
1264
|
+
cjs += ` },
|
|
1265
|
+
`;
|
|
1266
|
+
}
|
|
1267
|
+
cjs += "};\n";
|
|
1268
|
+
import_node_fs2.default.writeFileSync(cjsPath, cjs, "utf8");
|
|
1269
|
+
const esm = `// .adorn/validators.mjs (generated)
|
|
1270
|
+
import { createRequire } from "node:module";
|
|
1271
|
+
const require = createRequire(import.meta.url);
|
|
1272
|
+
const cjs = require("./validators.cjs");
|
|
1273
|
+
|
|
1274
|
+
export const validators = cjs.validators;
|
|
1275
|
+
|
|
1276
|
+
export function validateBody(operationId, data) {
|
|
1277
|
+
const v = validators?.[operationId]?.body;
|
|
1278
|
+
if (!v) return { ok: true, errors: null };
|
|
1279
|
+
const ok = v(data);
|
|
1280
|
+
return { ok, errors: ok ? null : v.errors };
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
export function validateResponse(operationId, status, contentType, data) {
|
|
1284
|
+
const key = String(status) + "|" + String(contentType);
|
|
1285
|
+
const v = validators?.[operationId]?.response?.[key];
|
|
1286
|
+
if (!v) return { ok: true, errors: null };
|
|
1287
|
+
const ok = v(data);
|
|
1288
|
+
return { ok, errors: ok ? null : v.errors };
|
|
1289
|
+
}
|
|
1290
|
+
`;
|
|
1291
|
+
import_node_fs2.default.writeFileSync(esmPath, esm, "utf8");
|
|
1292
|
+
const hash = import_node_crypto.default.createHash("sha256").update(cjs).digest("hex");
|
|
1293
|
+
import_node_fs2.default.writeFileSync(metaPath, JSON.stringify({ hash }, null, 2), "utf8");
|
|
1294
|
+
return { validatorsCjsPath: cjsPath, validatorsEsmPath: esmPath, hash };
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
// src/compiler/cache/isStale.ts
|
|
1298
|
+
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
1299
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
1300
|
+
var import_typescript7 = require("typescript");
|
|
1301
|
+
var import_meta = {};
|
|
1302
|
+
function readJson(p) {
|
|
1303
|
+
try {
|
|
1304
|
+
return JSON.parse(import_node_fs3.default.readFileSync(p, "utf8"));
|
|
1305
|
+
} catch {
|
|
1306
|
+
return null;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
function statMtimeMs(p) {
|
|
1310
|
+
try {
|
|
1311
|
+
return import_node_fs3.default.statSync(p).mtimeMs;
|
|
1312
|
+
} catch {
|
|
1313
|
+
return null;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
function ensureAbs(p) {
|
|
1317
|
+
return import_node_path3.default.isAbsolute(p) ? p : import_node_path3.default.resolve(p);
|
|
1318
|
+
}
|
|
1319
|
+
function collectTsconfigChain(tsconfigPathAbs) {
|
|
1320
|
+
const out = [];
|
|
1321
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1322
|
+
function visit(pAbs) {
|
|
1323
|
+
if (seen.has(pAbs)) return;
|
|
1324
|
+
seen.add(pAbs);
|
|
1325
|
+
out.push(pAbs);
|
|
1326
|
+
const raw = readJson(pAbs);
|
|
1327
|
+
const ext = raw?.extends;
|
|
1328
|
+
if (!ext) return;
|
|
1329
|
+
let resolved = null;
|
|
1330
|
+
if (ext.startsWith(".") || ext.startsWith("/") || /^[A-Za-z]:\\/.test(ext)) {
|
|
1331
|
+
resolved = ensureAbs(import_node_path3.default.resolve(import_node_path3.default.dirname(pAbs), ext));
|
|
1332
|
+
if (!resolved.endsWith(".json")) resolved += ".json";
|
|
1333
|
+
} else {
|
|
1334
|
+
try {
|
|
1335
|
+
const req = module.createRequire?.(import_meta.url) ?? require;
|
|
1336
|
+
resolved = req.resolve(ext);
|
|
1337
|
+
} catch {
|
|
1338
|
+
try {
|
|
1339
|
+
const req = module.createRequire?.(import_meta.url) ?? require;
|
|
1340
|
+
resolved = req.resolve(ext.endsWith(".json") ? ext : `${ext}.json`);
|
|
1341
|
+
} catch {
|
|
1342
|
+
resolved = null;
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
if (resolved) visit(resolved);
|
|
1347
|
+
}
|
|
1348
|
+
visit(tsconfigPathAbs);
|
|
1349
|
+
return out;
|
|
1350
|
+
}
|
|
1351
|
+
function findLockfile(startDir) {
|
|
1352
|
+
const names = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock"];
|
|
1353
|
+
let dir = startDir;
|
|
1354
|
+
for (let i = 0; i < 20; i++) {
|
|
1355
|
+
for (const n of names) {
|
|
1356
|
+
const p = import_node_path3.default.join(dir, n);
|
|
1357
|
+
const mt = statMtimeMs(p);
|
|
1358
|
+
if (mt != null) return { path: p, mtimeMs: mt };
|
|
1359
|
+
}
|
|
1360
|
+
const parent = import_node_path3.default.dirname(dir);
|
|
1361
|
+
if (parent === dir) break;
|
|
1362
|
+
dir = parent;
|
|
1363
|
+
}
|
|
1364
|
+
return null;
|
|
1365
|
+
}
|
|
1366
|
+
async function isStale(params) {
|
|
1367
|
+
const outDirAbs = ensureAbs(params.outDir);
|
|
1368
|
+
const tsconfigAbs = ensureAbs(params.project);
|
|
1369
|
+
const manifestPath = import_node_path3.default.join(outDirAbs, "manifest.json");
|
|
1370
|
+
const cachePath = import_node_path3.default.join(outDirAbs, "cache.json");
|
|
1371
|
+
if (!import_node_fs3.default.existsSync(manifestPath)) return { stale: true, reason: "missing-manifest" };
|
|
1372
|
+
const cache = readJson(cachePath);
|
|
1373
|
+
if (!cache) return { stale: true, reason: "missing-cache" };
|
|
1374
|
+
if (cache.generator.version !== params.adornVersion) {
|
|
1375
|
+
return { stale: true, reason: "generator-version-changed", detail: `${cache.generator.version} -> ${params.adornVersion}` };
|
|
1376
|
+
}
|
|
1377
|
+
if (ensureAbs(cache.project.tsconfigPath) !== tsconfigAbs) {
|
|
1378
|
+
return { stale: true, reason: "tsconfig-changed", detail: "different project path" };
|
|
1379
|
+
}
|
|
1380
|
+
const chain = collectTsconfigChain(tsconfigAbs);
|
|
1381
|
+
for (const cfg of chain) {
|
|
1382
|
+
const mt = statMtimeMs(cfg);
|
|
1383
|
+
if (mt == null) return { stale: true, reason: "config-missing", detail: cfg };
|
|
1384
|
+
const cachedMt = cache.project.configFiles[cfg];
|
|
1385
|
+
if (cachedMt == null || Math.abs(cachedMt - mt) > 1e-4) {
|
|
1386
|
+
return { stale: true, reason: "config-updated", detail: cfg };
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
if (cache.project.lockfile?.path) {
|
|
1390
|
+
const mt = statMtimeMs(cache.project.lockfile.path);
|
|
1391
|
+
if (mt == null) return { stale: true, reason: "lockfile-missing", detail: cache.project.lockfile.path };
|
|
1392
|
+
if (Math.abs(cache.project.lockfile.mtimeMs - mt) > 1e-4) {
|
|
1393
|
+
return { stale: true, reason: "lockfile-updated", detail: cache.project.lockfile.path };
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
for (const [file, cachedMt] of Object.entries(cache.inputs)) {
|
|
1397
|
+
const mt = statMtimeMs(file);
|
|
1398
|
+
if (mt == null) return { stale: true, reason: "input-missing", detail: file };
|
|
1399
|
+
if (Math.abs(cachedMt - mt) > 1e-4) return { stale: true, reason: "input-updated", detail: file };
|
|
1400
|
+
}
|
|
1401
|
+
return { stale: false, reason: "up-to-date" };
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
// src/compiler/cache/writeCache.ts
|
|
1405
|
+
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
1406
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
1407
|
+
var import_typescript8 = __toESM(require("typescript"), 1);
|
|
1408
|
+
function statMtimeMs2(p) {
|
|
1409
|
+
return import_node_fs4.default.statSync(p).mtimeMs;
|
|
1410
|
+
}
|
|
1411
|
+
function ensureDir(p) {
|
|
1412
|
+
import_node_fs4.default.mkdirSync(p, { recursive: true });
|
|
1413
|
+
}
|
|
1414
|
+
function isProjectSourceFile(f) {
|
|
1415
|
+
if (f.includes(`${import_node_path4.default.sep}node_modules${import_node_path4.default.sep}`)) return false;
|
|
1416
|
+
if (f.includes(`${import_node_path4.default.sep}typescript${import_node_path4.default.sep}lib${import_node_path4.default.sep}`)) return false;
|
|
1417
|
+
return /\.(ts|tsx|mts|cts)$/.test(f);
|
|
1418
|
+
}
|
|
1419
|
+
function writeCache(params) {
|
|
1420
|
+
const outDirAbs = import_node_path4.default.isAbsolute(params.outDir) ? params.outDir : import_node_path4.default.resolve(params.outDir);
|
|
1421
|
+
ensureDir(outDirAbs);
|
|
1422
|
+
const configFiles = collectTsconfigChain(params.tsconfigAbs);
|
|
1423
|
+
const configMtimes = {};
|
|
1424
|
+
for (const cfg of configFiles) configMtimes[cfg] = statMtimeMs2(cfg);
|
|
1425
|
+
const lock = findLockfile(import_node_path4.default.dirname(params.tsconfigAbs));
|
|
1426
|
+
const inputs = {};
|
|
1427
|
+
for (const sf of params.program.getSourceFiles()) {
|
|
1428
|
+
const f = sf.fileName;
|
|
1429
|
+
if (!isProjectSourceFile(f)) continue;
|
|
1430
|
+
try {
|
|
1431
|
+
inputs[f] = statMtimeMs2(f);
|
|
1432
|
+
} catch {
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
const cache = {
|
|
1436
|
+
cacheVersion: 1,
|
|
1437
|
+
generator: {
|
|
1438
|
+
name: "adorn-api",
|
|
1439
|
+
version: params.adornVersion,
|
|
1440
|
+
typescript: import_typescript8.default.version
|
|
1441
|
+
},
|
|
1442
|
+
project: {
|
|
1443
|
+
tsconfigPath: params.tsconfigAbs,
|
|
1444
|
+
configFiles: configMtimes,
|
|
1445
|
+
lockfile: lock ?? null
|
|
1446
|
+
},
|
|
1447
|
+
inputs
|
|
1448
|
+
};
|
|
1449
|
+
import_node_fs4.default.writeFileSync(import_node_path4.default.join(outDirAbs, "cache.json"), JSON.stringify(cache, null, 2), "utf8");
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
// src/cli.ts
|
|
1453
|
+
var import_typescript9 = __toESM(require("typescript"), 1);
|
|
1454
|
+
var import_node_process = __toESM(require("process"), 1);
|
|
1455
|
+
var ADORN_VERSION = "0.1.0";
|
|
1456
|
+
function log(msg) {
|
|
1457
|
+
import_node_process.default.stdout.write(msg + "\n");
|
|
1458
|
+
}
|
|
1459
|
+
function debug(...args) {
|
|
1460
|
+
if (import_node_process.default.env.ADORN_DEBUG) {
|
|
1461
|
+
console.error("[adorn-api]", ...args);
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
async function buildCommand(args) {
|
|
1465
|
+
const projectIndex = args.indexOf("-p");
|
|
1466
|
+
const projectPath = projectIndex !== -1 ? args[projectIndex + 1] : "./tsconfig.json";
|
|
1467
|
+
const outputDir = args.includes("--output") ? args[args.indexOf("--output") + 1] : ".adorn";
|
|
1468
|
+
const ifStale = args.includes("--if-stale");
|
|
1469
|
+
const validationModeIndex = args.indexOf("--validation-mode");
|
|
1470
|
+
const validationMode = validationModeIndex !== -1 ? args[validationModeIndex + 1] : "ajv-runtime";
|
|
1471
|
+
if (validationMode !== "none" && validationMode !== "ajv-runtime" && validationMode !== "precompiled") {
|
|
1472
|
+
console.error(`Invalid validation mode: ${validationMode}. Valid values: none, ajv-runtime, precompiled`);
|
|
1473
|
+
import_node_process.default.exit(1);
|
|
1474
|
+
}
|
|
1475
|
+
const outputPath = (0, import_node_path5.resolve)(outputDir);
|
|
1476
|
+
if (ifStale) {
|
|
1477
|
+
const stale = await isStale({
|
|
1478
|
+
outDir: outputDir,
|
|
1479
|
+
project: projectPath,
|
|
1480
|
+
adornVersion: ADORN_VERSION,
|
|
1481
|
+
typescriptVersion: import_typescript9.default.version
|
|
1482
|
+
});
|
|
1483
|
+
if (!stale.stale) {
|
|
1484
|
+
log("adorn-api: artifacts up-to-date");
|
|
1485
|
+
return;
|
|
1486
|
+
}
|
|
1487
|
+
log(`adorn-api: building artifacts (reason: ${stale.reason}${stale.detail ? `: ${stale.detail}` : ""})`);
|
|
1488
|
+
debug("Stale detail:", stale.detail);
|
|
1489
|
+
} else {
|
|
1490
|
+
log("adorn-api: building artifacts (reason: forced-build)");
|
|
1491
|
+
}
|
|
1492
|
+
const { program, checker, sourceFiles } = createProgramFromConfig(projectPath);
|
|
1493
|
+
const controllers = scanControllers(sourceFiles, checker);
|
|
1494
|
+
if (controllers.length === 0) {
|
|
1495
|
+
console.warn("No controllers found!");
|
|
1496
|
+
import_node_process.default.exit(1);
|
|
1497
|
+
}
|
|
1498
|
+
log(`Found ${controllers.length} controller(s)`);
|
|
1499
|
+
const openapi = generateOpenAPI(controllers, checker, { title: "API", version: "1.0.0" });
|
|
1500
|
+
const manifest = generateManifest(controllers, checker, ADORN_VERSION, validationMode);
|
|
1501
|
+
(0, import_node_fs5.mkdirSync)(outputPath, { recursive: true });
|
|
1502
|
+
(0, import_node_fs5.writeFileSync)((0, import_node_path5.resolve)(outputPath, "openapi.json"), JSON.stringify(openapi, null, 2));
|
|
1503
|
+
(0, import_node_fs5.writeFileSync)((0, import_node_path5.resolve)(outputPath, "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
1504
|
+
if (validationMode === "precompiled") {
|
|
1505
|
+
log("Generating precompiled validators...");
|
|
1506
|
+
const manifestObj = JSON.parse((0, import_node_fs5.readFileSync)((0, import_node_path5.resolve)(outputPath, "manifest.json"), "utf-8"));
|
|
1507
|
+
await emitPrecompiledValidators({
|
|
1508
|
+
outDir: outputPath,
|
|
1509
|
+
openapi,
|
|
1510
|
+
manifest: manifestObj,
|
|
1511
|
+
strict: "off",
|
|
1512
|
+
formatsMode: "full"
|
|
1513
|
+
});
|
|
1514
|
+
manifestObj.validation = {
|
|
1515
|
+
mode: "precompiled",
|
|
1516
|
+
precompiledModule: "./validators.mjs"
|
|
1517
|
+
};
|
|
1518
|
+
(0, import_node_fs5.writeFileSync)((0, import_node_path5.resolve)(outputPath, "manifest.json"), JSON.stringify(manifestObj, null, 2));
|
|
1519
|
+
log(" - validators.cjs");
|
|
1520
|
+
log(" - validators.mjs");
|
|
1521
|
+
log(" - validators.meta.json");
|
|
1522
|
+
}
|
|
1523
|
+
writeCache({
|
|
1524
|
+
outDir: outputDir,
|
|
1525
|
+
tsconfigAbs: (0, import_node_path5.resolve)(projectPath),
|
|
1526
|
+
program,
|
|
1527
|
+
adornVersion: ADORN_VERSION
|
|
1528
|
+
});
|
|
1529
|
+
log(`Written to ${outputPath}/`);
|
|
1530
|
+
log(" - openapi.json");
|
|
1531
|
+
log(" - manifest.json");
|
|
1532
|
+
log(" - cache.json");
|
|
1533
|
+
}
|
|
1534
|
+
function cleanCommand(args) {
|
|
1535
|
+
const outputDir = args.includes("--output") ? args[args.indexOf("--output") + 1] : ".adorn";
|
|
1536
|
+
const outputPath = (0, import_node_path5.resolve)(outputDir);
|
|
1537
|
+
if ((0, import_node_fs5.existsSync)(outputPath)) {
|
|
1538
|
+
(0, import_node_fs5.rmSync)(outputPath, { recursive: true, force: true });
|
|
1539
|
+
}
|
|
1540
|
+
log(`adorn-api: cleaned ${outputDir}`);
|
|
1541
|
+
}
|
|
1542
|
+
var command = import_node_process.default.argv[2];
|
|
1543
|
+
if (command === "build") {
|
|
1544
|
+
buildCommand(import_node_process.default.argv.slice(3)).catch((err) => {
|
|
1545
|
+
console.error(err);
|
|
1546
|
+
import_node_process.default.exit(1);
|
|
1547
|
+
});
|
|
1548
|
+
} else if (command === "clean") {
|
|
1549
|
+
cleanCommand(import_node_process.default.argv.slice(3));
|
|
1550
|
+
} else {
|
|
1551
|
+
console.log(`
|
|
1552
|
+
adorn-api CLI
|
|
1553
|
+
|
|
1554
|
+
Commands:
|
|
1555
|
+
build Generate OpenAPI and manifest from TypeScript source
|
|
1556
|
+
clean Remove generated artifacts
|
|
1557
|
+
|
|
1558
|
+
Options:
|
|
1559
|
+
-p <path> Path to tsconfig.json (default: ./tsconfig.json)
|
|
1560
|
+
--output <dir> Output directory (default: .adorn)
|
|
1561
|
+
--if-stale Only rebuild if artifacts are stale
|
|
1562
|
+
--validation-mode <mode> Validation mode: none, ajv-runtime, precompiled (default: ajv-runtime)
|
|
1563
|
+
|
|
1564
|
+
Examples:
|
|
1565
|
+
adorn-api build -p ./tsconfig.json --output .adorn
|
|
1566
|
+
adorn-api build --if-stale
|
|
1567
|
+
adorn-api build --validation-mode precompiled
|
|
1568
|
+
adorn-api clean
|
|
1569
|
+
`);
|
|
1570
|
+
}
|
|
1571
|
+
//# sourceMappingURL=cli.cjs.map
|