@redocly/client-generator 0.3.8 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -54
- package/eject-assets/AGENTS.md +137 -0
- package/eject-assets/generators/cli/docs.ts +224 -0
- package/eject-assets/generators/cli/engine-source.ts +21 -0
- package/eject-assets/generators/cli/index.ts +90 -0
- package/eject-assets/generators/cli/render.ts +348 -0
- package/eject-assets/generators/go/client.ts +57 -0
- package/eject-assets/generators/go/descriptor.ts +41 -0
- package/eject-assets/generators/go/index.ts +336 -0
- package/eject-assets/generators/go/models.ts +179 -0
- package/eject-assets/generators/go/naming.ts +49 -0
- package/eject-assets/generators/go/operations.ts +296 -0
- package/eject-assets/generators/go/pagination.ts +194 -0
- package/eject-assets/generators/go/types.ts +60 -0
- package/eject-assets/generators/mock/faker.ts +214 -0
- package/eject-assets/generators/mock/index.ts +35 -0
- package/eject-assets/generators/mock/render.ts +282 -0
- package/eject-assets/generators/mock/sample.ts +316 -0
- package/eject-assets/generators/mock/values.ts +63 -0
- package/eject-assets/generators/php/client.ts +63 -0
- package/eject-assets/generators/php/descriptor.ts +58 -0
- package/eject-assets/generators/php/index.ts +237 -0
- package/eject-assets/generators/php/models.ts +275 -0
- package/eject-assets/generators/php/naming.ts +51 -0
- package/eject-assets/generators/php/operations.ts +232 -0
- package/eject-assets/generators/php/pagination.ts +133 -0
- package/eject-assets/generators/php/types.ts +148 -0
- package/eject-assets/generators/python/client.ts +123 -0
- package/eject-assets/generators/python/descriptor.ts +52 -0
- package/eject-assets/generators/python/index.ts +251 -0
- package/eject-assets/generators/python/models.ts +242 -0
- package/eject-assets/generators/python/naming.ts +46 -0
- package/eject-assets/generators/python/operations.ts +147 -0
- package/eject-assets/generators/python/pagination.ts +128 -0
- package/eject-assets/generators/python/types.ts +54 -0
- package/eject-assets/generators/swr/index.ts +37 -0
- package/eject-assets/generators/swr/render.ts +78 -0
- package/eject-assets/generators/tanstack-query/index.ts +48 -0
- package/eject-assets/generators/tanstack-query/render.ts +346 -0
- package/eject-assets/generators/transformers/index.ts +46 -0
- package/eject-assets/generators/transformers/render.ts +506 -0
- package/eject-assets/generators/typescript/banner.ts +35 -0
- package/eject-assets/generators/typescript/client.ts +254 -0
- package/eject-assets/generators/typescript/descriptor.ts +137 -0
- package/eject-assets/generators/typescript/index.ts +101 -0
- package/eject-assets/generators/typescript/inline-runtime.ts +135 -0
- package/eject-assets/generators/typescript/operation-signature.ts +62 -0
- package/eject-assets/generators/typescript/operation-types.ts +17 -0
- package/eject-assets/generators/typescript/operations.ts +524 -0
- package/eject-assets/generators/typescript/response-headers.ts +74 -0
- package/eject-assets/generators/typescript/type-guards.ts +159 -0
- package/eject-assets/generators/typescript/types.ts +172 -0
- package/eject-assets/generators/zod/index.ts +32 -0
- package/eject-assets/generators/zod/schemas.ts +456 -0
- package/eject-assets/skills/cli-generator/SKILL.md +121 -0
- package/eject-assets/skills/client-generators/SKILL.md +142 -0
- package/eject-assets/skills/go-generator/SKILL.md +96 -0
- package/eject-assets/skills/mock-generator/SKILL.md +50 -0
- package/eject-assets/skills/php-generator/SKILL.md +112 -0
- package/eject-assets/skills/python-generator/SKILL.md +110 -0
- package/eject-assets/skills/swr-generator/SKILL.md +50 -0
- package/eject-assets/skills/tanstack-query-generator/SKILL.md +55 -0
- package/eject-assets/skills/transformers-generator/SKILL.md +47 -0
- package/eject-assets/skills/typescript-generator/SKILL.md +95 -0
- package/eject-assets/skills/zod-generator/SKILL.md +54 -0
- package/lib/authoring/index.d.ts +11 -0
- package/lib/authoring/index.d.ts.map +1 -0
- package/lib/authoring/index.js +42 -0
- package/lib/authoring/index.js.map +1 -0
- package/lib/authoring/naming.d.ts +34 -0
- package/lib/authoring/naming.d.ts.map +1 -0
- package/lib/authoring/naming.js +104 -0
- package/lib/authoring/naming.js.map +1 -0
- package/lib/authoring/operation.d.ts +47 -0
- package/lib/authoring/operation.d.ts.map +1 -0
- package/lib/authoring/operation.js +86 -0
- package/lib/authoring/operation.js.map +1 -0
- package/lib/authoring/options.d.ts +9 -0
- package/lib/authoring/options.d.ts.map +1 -0
- package/lib/authoring/options.js +5 -0
- package/lib/authoring/options.js.map +1 -0
- package/lib/authoring/pagination.d.ts +19 -0
- package/lib/authoring/pagination.d.ts.map +1 -0
- package/lib/authoring/pagination.js +45 -0
- package/lib/authoring/pagination.js.map +1 -0
- package/lib/authoring/printer.d.ts +16 -0
- package/lib/authoring/printer.d.ts.map +1 -0
- package/lib/authoring/printer.js +36 -0
- package/lib/authoring/printer.js.map +1 -0
- package/lib/authoring/reference-page.d.ts +31 -0
- package/lib/authoring/reference-page.d.ts.map +1 -0
- package/lib/authoring/reference-page.js +160 -0
- package/lib/authoring/reference-page.js.map +1 -0
- package/lib/authoring/schema.d.ts +51 -0
- package/lib/authoring/schema.d.ts.map +1 -0
- package/lib/authoring/schema.js +190 -0
- package/lib/authoring/schema.js.map +1 -0
- package/lib/cli-contract.d.ts +126 -0
- package/lib/cli-contract.d.ts.map +1 -0
- package/lib/cli-contract.js +25 -0
- package/lib/cli-contract.js.map +1 -0
- package/lib/{emitters/wrapper-support.d.ts → contracts/typescript.d.ts} +13 -24
- package/lib/contracts/typescript.d.ts.map +1 -0
- package/lib/contracts/typescript.js +87 -0
- package/lib/contracts/typescript.js.map +1 -0
- package/lib/generate.d.ts +10 -10
- package/lib/generate.d.ts.map +1 -1
- package/lib/generate.js +25 -106
- package/lib/generate.js.map +1 -1
- package/lib/generators/cli/docs.d.ts +19 -0
- package/lib/generators/cli/docs.d.ts.map +1 -0
- package/lib/generators/cli/docs.js +187 -0
- package/lib/generators/cli/docs.js.map +1 -0
- package/lib/generators/cli/engine-source.d.ts +5 -0
- package/lib/generators/cli/engine-source.d.ts.map +1 -0
- package/lib/generators/cli/engine-source.js +12 -0
- package/lib/generators/cli/engine-source.js.map +1 -0
- package/lib/generators/cli/index.d.ts +18 -0
- package/lib/generators/cli/index.d.ts.map +1 -0
- package/lib/generators/cli/index.js +67 -0
- package/lib/generators/cli/index.js.map +1 -0
- package/lib/generators/cli/render.d.ts +39 -0
- package/lib/generators/cli/render.d.ts.map +1 -0
- package/lib/generators/cli/render.js +281 -0
- package/lib/generators/cli/render.js.map +1 -0
- package/lib/generators/cli/runtime/cli.d.ts +42 -0
- package/lib/generators/cli/runtime/cli.d.ts.map +1 -0
- package/lib/generators/cli/runtime/cli.js +582 -0
- package/lib/generators/cli/runtime/cli.js.map +1 -0
- package/lib/generators/compatibility.d.ts +10 -0
- package/lib/generators/compatibility.d.ts.map +1 -0
- package/lib/generators/compatibility.js +45 -0
- package/lib/generators/compatibility.js.map +1 -0
- package/lib/generators/go/client.d.ts +5 -0
- package/lib/generators/go/client.d.ts.map +1 -0
- package/lib/generators/go/client.js +34 -0
- package/lib/generators/go/client.js.map +1 -0
- package/lib/generators/go/descriptor.d.ts +6 -0
- package/lib/generators/go/descriptor.d.ts.map +1 -0
- package/lib/generators/go/descriptor.js +26 -0
- package/lib/generators/go/descriptor.js.map +1 -0
- package/lib/generators/go/index.d.ts +14 -0
- package/lib/generators/go/index.d.ts.map +1 -0
- package/lib/generators/go/index.js +240 -0
- package/lib/generators/go/index.js.map +1 -0
- package/lib/generators/go/models.d.ts +4 -0
- package/lib/generators/go/models.d.ts.map +1 -0
- package/lib/generators/go/models.js +125 -0
- package/lib/generators/go/models.js.map +1 -0
- package/lib/generators/go/naming.d.ts +15 -0
- package/lib/generators/go/naming.d.ts.map +1 -0
- package/lib/generators/go/naming.js +36 -0
- package/lib/generators/go/naming.js.map +1 -0
- package/lib/generators/go/operations.d.ts +16 -0
- package/lib/generators/go/operations.d.ts.map +1 -0
- package/lib/generators/go/operations.js +200 -0
- package/lib/generators/go/operations.js.map +1 -0
- package/lib/generators/go/pagination.d.ts +5 -0
- package/lib/generators/go/pagination.d.ts.map +1 -0
- package/lib/generators/go/pagination.js +93 -0
- package/lib/generators/go/pagination.js.map +1 -0
- package/lib/generators/go/types.d.ts +4 -0
- package/lib/generators/go/types.d.ts.map +1 -0
- package/lib/generators/go/types.js +48 -0
- package/lib/generators/go/types.js.map +1 -0
- package/lib/generators/index.d.ts +2 -3
- package/lib/generators/index.d.ts.map +1 -1
- package/lib/generators/index.js +31 -53
- package/lib/generators/index.js.map +1 -1
- package/lib/generators/meta.d.ts +13 -0
- package/lib/generators/meta.d.ts.map +1 -0
- package/lib/generators/meta.js +157 -0
- package/lib/generators/meta.js.map +1 -0
- package/lib/{emitters → generators/mock}/faker.d.ts +4 -5
- package/lib/generators/mock/faker.d.ts.map +1 -0
- package/lib/generators/mock/faker.js +180 -0
- package/lib/generators/mock/faker.js.map +1 -0
- package/lib/generators/{mock.d.ts → mock/index.d.ts} +2 -2
- package/lib/generators/mock/index.d.ts.map +1 -0
- package/lib/generators/{mock.js → mock/index.js} +8 -8
- package/lib/generators/mock/index.js.map +1 -0
- package/lib/{emitters/mock.d.ts → generators/mock/render.d.ts} +2 -3
- package/lib/generators/mock/render.d.ts.map +1 -0
- package/lib/generators/mock/render.js +228 -0
- package/lib/generators/mock/render.js.map +1 -0
- package/lib/{emitters → generators/mock}/sample.d.ts +1 -2
- package/lib/generators/mock/sample.d.ts.map +1 -0
- package/lib/generators/mock/sample.js.map +1 -0
- package/lib/generators/mock/values.d.ts +33 -0
- package/lib/generators/mock/values.d.ts.map +1 -0
- package/lib/generators/mock/values.js +46 -0
- package/lib/generators/mock/values.js.map +1 -0
- package/lib/generators/options.d.ts +7 -0
- package/lib/generators/options.d.ts.map +1 -0
- package/lib/generators/options.js +74 -0
- package/lib/generators/options.js.map +1 -0
- package/lib/generators/php/client.d.ts +5 -0
- package/lib/generators/php/client.d.ts.map +1 -0
- package/lib/generators/php/client.js +38 -0
- package/lib/generators/php/client.js.map +1 -0
- package/lib/generators/php/descriptor.d.ts +7 -0
- package/lib/generators/php/descriptor.d.ts.map +1 -0
- package/lib/generators/php/descriptor.js +42 -0
- package/lib/generators/php/descriptor.js.map +1 -0
- package/lib/generators/php/index.d.ts +14 -0
- package/lib/generators/php/index.d.ts.map +1 -0
- package/lib/generators/php/index.js +166 -0
- package/lib/generators/php/index.js.map +1 -0
- package/lib/generators/php/models.d.ts +8 -0
- package/lib/generators/php/models.d.ts.map +1 -0
- package/lib/generators/php/models.js +200 -0
- package/lib/generators/php/models.js.map +1 -0
- package/lib/generators/php/naming.d.ts +16 -0
- package/lib/generators/php/naming.d.ts.map +1 -0
- package/lib/generators/php/naming.js +31 -0
- package/lib/generators/php/naming.js.map +1 -0
- package/lib/generators/php/operations.d.ts +21 -0
- package/lib/generators/php/operations.d.ts.map +1 -0
- package/lib/generators/php/operations.js +156 -0
- package/lib/generators/php/operations.js.map +1 -0
- package/lib/generators/php/pagination.d.ts +5 -0
- package/lib/generators/php/pagination.d.ts.map +1 -0
- package/lib/generators/php/pagination.js +68 -0
- package/lib/generators/php/pagination.js.map +1 -0
- package/lib/generators/php/types.d.ts +27 -0
- package/lib/generators/php/types.d.ts.map +1 -0
- package/lib/generators/php/types.js +128 -0
- package/lib/generators/php/types.js.map +1 -0
- package/lib/generators/python/client.d.ts +6 -0
- package/lib/generators/python/client.d.ts.map +1 -0
- package/lib/generators/python/client.js +80 -0
- package/lib/generators/python/client.js.map +1 -0
- package/lib/generators/python/descriptor.d.ts +9 -0
- package/lib/generators/python/descriptor.d.ts.map +1 -0
- package/lib/generators/python/descriptor.js +38 -0
- package/lib/generators/python/descriptor.js.map +1 -0
- package/lib/generators/python/index.d.ts +15 -0
- package/lib/generators/python/index.d.ts.map +1 -0
- package/lib/generators/python/index.js +197 -0
- package/lib/generators/python/index.js.map +1 -0
- package/lib/generators/python/models.d.ts +31 -0
- package/lib/generators/python/models.d.ts.map +1 -0
- package/lib/generators/python/models.js +203 -0
- package/lib/generators/python/models.js.map +1 -0
- package/lib/generators/python/naming.d.ts +22 -0
- package/lib/generators/python/naming.d.ts.map +1 -0
- package/lib/generators/python/naming.js +28 -0
- package/lib/generators/python/naming.js.map +1 -0
- package/lib/generators/python/operations.d.ts +4 -0
- package/lib/generators/python/operations.d.ts.map +1 -0
- package/lib/generators/python/operations.js +108 -0
- package/lib/generators/python/operations.js.map +1 -0
- package/lib/generators/python/pagination.d.ts +5 -0
- package/lib/generators/python/pagination.d.ts.map +1 -0
- package/lib/generators/python/pagination.js +95 -0
- package/lib/generators/python/pagination.js.map +1 -0
- package/lib/generators/python/types.d.ts +4 -0
- package/lib/generators/python/types.d.ts.map +1 -0
- package/lib/generators/python/types.js +45 -0
- package/lib/generators/python/types.js.map +1 -0
- package/lib/generators/resolve.d.ts.map +1 -1
- package/lib/generators/resolve.js +92 -13
- package/lib/generators/resolve.js.map +1 -1
- package/lib/generators/{swr.d.ts → swr/index.d.ts} +3 -3
- package/lib/generators/swr/index.d.ts.map +1 -0
- package/lib/generators/{swr.js → swr/index.js} +7 -10
- package/lib/generators/swr/index.js.map +1 -0
- package/lib/{emitters/swr.d.ts → generators/swr/render.d.ts} +2 -4
- package/lib/generators/swr/render.d.ts.map +1 -0
- package/lib/generators/swr/render.js +57 -0
- package/lib/generators/swr/render.js.map +1 -0
- package/lib/generators/{tanstack-query.d.ts → tanstack-query/index.d.ts} +3 -3
- package/lib/generators/tanstack-query/index.d.ts.map +1 -0
- package/lib/generators/{tanstack-query.js → tanstack-query/index.js} +11 -10
- package/lib/generators/tanstack-query/index.js.map +1 -0
- package/lib/{emitters/tanstack-query.d.ts → generators/tanstack-query/render.d.ts} +6 -5
- package/lib/generators/tanstack-query/render.d.ts.map +1 -0
- package/lib/{emitters/tanstack-query.js → generators/tanstack-query/render.js} +33 -21
- package/lib/generators/tanstack-query/render.js.map +1 -0
- package/lib/generators/{transformers.d.ts → transformers/index.d.ts} +2 -2
- package/lib/generators/transformers/index.d.ts.map +1 -0
- package/lib/generators/{transformers.js → transformers/index.js} +11 -8
- package/lib/generators/transformers/index.js.map +1 -0
- package/lib/{emitters/transformers.d.ts → generators/transformers/render.d.ts} +2 -2
- package/lib/generators/transformers/render.d.ts.map +1 -0
- package/lib/{emitters/transformers.js → generators/transformers/render.js} +125 -165
- package/lib/generators/transformers/render.js.map +1 -0
- package/lib/generators/types.d.ts +190 -12
- package/lib/generators/types.d.ts.map +1 -1
- package/lib/generators/typescript/banner.d.ts +12 -0
- package/lib/generators/typescript/banner.d.ts.map +1 -0
- package/lib/{emitters/emit-options.js → generators/typescript/banner.js} +2 -3
- package/lib/generators/typescript/banner.js.map +1 -0
- package/lib/generators/typescript/client.d.ts +25 -0
- package/lib/generators/typescript/client.d.ts.map +1 -0
- package/lib/generators/typescript/client.js +207 -0
- package/lib/generators/typescript/client.js.map +1 -0
- package/lib/generators/typescript/descriptor.d.ts +11 -0
- package/lib/generators/typescript/descriptor.d.ts.map +1 -0
- package/lib/generators/typescript/descriptor.js +97 -0
- package/lib/generators/typescript/descriptor.js.map +1 -0
- package/lib/generators/typescript/index.d.ts +20 -0
- package/lib/generators/typescript/index.d.ts.map +1 -0
- package/lib/generators/typescript/index.js +80 -0
- package/lib/generators/typescript/index.js.map +1 -0
- package/lib/generators/typescript/inline-runtime.d.ts +21 -0
- package/lib/generators/typescript/inline-runtime.d.ts.map +1 -0
- package/lib/generators/typescript/inline-runtime.js +114 -0
- package/lib/generators/typescript/inline-runtime.js.map +1 -0
- package/lib/generators/typescript/operation-signature.d.ts +23 -0
- package/lib/generators/typescript/operation-signature.d.ts.map +1 -0
- package/lib/generators/typescript/operation-signature.js +41 -0
- package/lib/generators/typescript/operation-signature.js.map +1 -0
- package/lib/generators/typescript/operation-types.d.ts +9 -0
- package/lib/generators/typescript/operation-types.d.ts.map +1 -0
- package/lib/generators/typescript/operation-types.js +11 -0
- package/lib/generators/typescript/operation-types.js.map +1 -0
- package/lib/generators/typescript/operations.d.ts +60 -0
- package/lib/generators/typescript/operations.d.ts.map +1 -0
- package/lib/generators/typescript/operations.js +386 -0
- package/lib/generators/typescript/operations.js.map +1 -0
- package/lib/generators/typescript/response-headers.d.ts +12 -0
- package/lib/generators/typescript/response-headers.d.ts.map +1 -0
- package/lib/generators/typescript/response-headers.js +40 -0
- package/lib/generators/typescript/response-headers.js.map +1 -0
- package/lib/generators/typescript/runtime/auth.d.ts.map +1 -0
- package/lib/generators/typescript/runtime/auth.js.map +1 -0
- package/lib/{runtime → generators/typescript/runtime}/create-client.d.ts +7 -2
- package/lib/generators/typescript/runtime/create-client.d.ts.map +1 -0
- package/lib/{runtime → generators/typescript/runtime}/create-client.js +84 -30
- package/lib/generators/typescript/runtime/create-client.js.map +1 -0
- package/lib/generators/typescript/runtime/errors.d.ts.map +1 -0
- package/lib/generators/typescript/runtime/errors.js.map +1 -0
- package/lib/generators/typescript/runtime/index.d.ts.map +1 -0
- package/lib/generators/typescript/runtime/index.js.map +1 -0
- package/lib/generators/typescript/runtime/multipart.d.ts.map +1 -0
- package/lib/generators/typescript/runtime/multipart.js.map +1 -0
- package/lib/{runtime → generators/typescript/runtime}/paginate.d.ts +2 -2
- package/lib/generators/typescript/runtime/paginate.d.ts.map +1 -0
- package/lib/{runtime → generators/typescript/runtime}/paginate.js +12 -12
- package/lib/generators/typescript/runtime/paginate.js.map +1 -0
- package/lib/generators/typescript/runtime/parse.d.ts.map +1 -0
- package/lib/generators/typescript/runtime/parse.js.map +1 -0
- package/lib/generators/typescript/runtime/retry.d.ts.map +1 -0
- package/lib/generators/typescript/runtime/retry.js.map +1 -0
- package/lib/generators/typescript/runtime/send.d.ts.map +1 -0
- package/lib/generators/typescript/runtime/send.js.map +1 -0
- package/lib/generators/typescript/runtime/setup.d.ts.map +1 -0
- package/lib/generators/typescript/runtime/setup.js.map +1 -0
- package/lib/generators/typescript/runtime/sse.d.ts.map +1 -0
- package/lib/generators/typescript/runtime/sse.js.map +1 -0
- package/lib/{runtime → generators/typescript/runtime}/types.d.ts +17 -95
- package/lib/generators/typescript/runtime/types.d.ts.map +1 -0
- package/lib/generators/typescript/runtime/types.js.map +1 -0
- package/lib/generators/typescript/runtime/url.d.ts.map +1 -0
- package/lib/generators/typescript/runtime/url.js.map +1 -0
- package/lib/generators/typescript/type-guards.d.ts +4 -0
- package/lib/generators/typescript/type-guards.d.ts.map +1 -0
- package/lib/{emitters → generators/typescript}/type-guards.js +18 -52
- package/lib/generators/typescript/type-guards.js.map +1 -0
- package/lib/generators/typescript/types.d.ts +8 -0
- package/lib/generators/typescript/types.d.ts.map +1 -0
- package/lib/generators/typescript/types.js +132 -0
- package/lib/generators/typescript/types.js.map +1 -0
- package/lib/generators/{zod.d.ts → zod/index.d.ts} +2 -2
- package/lib/generators/zod/index.d.ts.map +1 -0
- package/lib/generators/{zod.js → zod/index.js} +5 -7
- package/lib/generators/zod/index.js.map +1 -0
- package/lib/{emitters/zod.d.ts → generators/zod/schemas.d.ts} +4 -5
- package/lib/generators/zod/schemas.d.ts.map +1 -0
- package/lib/{emitters/zod.js → generators/zod/schemas.js} +118 -154
- package/lib/generators/zod/schemas.js.map +1 -0
- package/lib/index.d.ts +8 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +18 -11
- package/lib/index.js.map +1 -1
- package/lib/intermediate-representation/build.d.ts +8 -1
- package/lib/intermediate-representation/build.d.ts.map +1 -1
- package/lib/intermediate-representation/build.js +59 -4
- package/lib/intermediate-representation/build.js.map +1 -1
- package/lib/intermediate-representation/model.d.ts +26 -1
- package/lib/intermediate-representation/model.d.ts.map +1 -1
- package/lib/intermediate-representation/model.js.map +1 -1
- package/lib/intermediate-representation/sanitize-identifiers.d.ts +1 -10
- package/lib/intermediate-representation/sanitize-identifiers.d.ts.map +1 -1
- package/lib/intermediate-representation/sanitize-identifiers.js +37 -38
- package/lib/intermediate-representation/sanitize-identifiers.js.map +1 -1
- package/lib/{emitters/pagination.d.ts → pagination.d.ts} +39 -15
- package/lib/pagination.d.ts.map +1 -0
- package/lib/{emitters/pagination.js → pagination.js} +13 -52
- package/lib/pagination.js.map +1 -0
- package/lib/pipeline.d.ts +17 -0
- package/lib/pipeline.d.ts.map +1 -0
- package/lib/pipeline.js +244 -0
- package/lib/pipeline.js.map +1 -0
- package/lib/plugin.d.ts +4 -4
- package/lib/plugin.d.ts.map +1 -1
- package/lib/plugin.js +12 -9
- package/lib/plugin.js.map +1 -1
- package/lib/printers/go.d.ts +33 -0
- package/lib/printers/go.d.ts.map +1 -0
- package/lib/printers/go.js +209 -0
- package/lib/printers/go.js.map +1 -0
- package/lib/printers/index.d.ts +5 -0
- package/lib/printers/index.d.ts.map +1 -0
- package/lib/printers/index.js +9 -0
- package/lib/printers/index.js.map +1 -0
- package/lib/printers/php.d.ts +21 -0
- package/lib/printers/php.d.ts.map +1 -0
- package/lib/printers/php.js +68 -0
- package/lib/printers/php.js.map +1 -0
- package/lib/printers/python.d.ts +31 -0
- package/lib/printers/python.d.ts.map +1 -0
- package/lib/printers/python.js +101 -0
- package/lib/printers/python.js.map +1 -0
- package/lib/printers/typescript.d.ts +82 -0
- package/lib/printers/typescript.d.ts.map +1 -0
- package/lib/printers/typescript.js +268 -0
- package/lib/printers/typescript.js.map +1 -0
- package/lib/reserved-names.d.ts +8 -0
- package/lib/reserved-names.d.ts.map +1 -0
- package/lib/{emitters/reserved-names.js → reserved-names.js} +16 -27
- package/lib/reserved-names.js.map +1 -0
- package/lib/runtime-contract.d.ts +62 -2
- package/lib/runtime-contract.d.ts.map +1 -1
- package/lib/runtime-contract.js +3 -3
- package/lib/runtime-contract.js.map +1 -1
- package/lib/runtime-sources/go.d.ts +2 -0
- package/lib/runtime-sources/go.d.ts.map +1 -0
- package/lib/runtime-sources/go.js +3 -0
- package/lib/runtime-sources/go.js.map +1 -0
- package/lib/runtime-sources/php.d.ts +2 -0
- package/lib/runtime-sources/php.d.ts.map +1 -0
- package/lib/runtime-sources/php.js +3 -0
- package/lib/runtime-sources/php.js.map +1 -0
- package/lib/runtime-sources/python.d.ts +12 -0
- package/lib/runtime-sources/python.d.ts.map +1 -0
- package/lib/runtime-sources/python.js +12 -0
- package/lib/runtime-sources/python.js.map +1 -0
- package/lib/runtime-sources/typescript.d.ts +36 -0
- package/lib/runtime-sources/typescript.d.ts.map +1 -0
- package/lib/runtime-sources/typescript.js +152 -0
- package/lib/runtime-sources/typescript.js.map +1 -0
- package/lib/runtime-sources.d.ts +5 -0
- package/lib/runtime-sources.d.ts.map +1 -0
- package/lib/runtime-sources.js +10 -0
- package/lib/runtime-sources.js.map +1 -0
- package/lib/setup-bake.d.ts.map +1 -0
- package/lib/{emitters/setup-bake.js → setup-bake.js} +11 -2
- package/lib/setup-bake.js.map +1 -0
- package/lib/types.d.ts +38 -8
- package/lib/types.d.ts.map +1 -1
- package/package.json +40 -4
- package/lib/emitters/auth.d.ts +0 -14
- package/lib/emitters/auth.d.ts.map +0 -1
- package/lib/emitters/auth.js +0 -30
- package/lib/emitters/auth.js.map +0 -1
- package/lib/emitters/client-assembly.d.ts +0 -15
- package/lib/emitters/client-assembly.d.ts.map +0 -1
- package/lib/emitters/client-assembly.js +0 -358
- package/lib/emitters/client-assembly.js.map +0 -1
- package/lib/emitters/descriptor.d.ts +0 -22
- package/lib/emitters/descriptor.d.ts.map +0 -1
- package/lib/emitters/descriptor.js +0 -199
- package/lib/emitters/descriptor.js.map +0 -1
- package/lib/emitters/emit-options.d.ts +0 -67
- package/lib/emitters/emit-options.d.ts.map +0 -1
- package/lib/emitters/emit-options.js.map +0 -1
- package/lib/emitters/faker.d.ts.map +0 -1
- package/lib/emitters/faker.js +0 -221
- package/lib/emitters/faker.js.map +0 -1
- package/lib/emitters/identifier.d.ts +0 -34
- package/lib/emitters/identifier.d.ts.map +0 -1
- package/lib/emitters/identifier.js +0 -104
- package/lib/emitters/identifier.js.map +0 -1
- package/lib/emitters/inline-runtime.d.ts +0 -11
- package/lib/emitters/inline-runtime.d.ts.map +0 -1
- package/lib/emitters/inline-runtime.js +0 -99
- package/lib/emitters/inline-runtime.js.map +0 -1
- package/lib/emitters/jsdoc.d.ts +0 -9
- package/lib/emitters/jsdoc.d.ts.map +0 -1
- package/lib/emitters/jsdoc.js +0 -83
- package/lib/emitters/jsdoc.js.map +0 -1
- package/lib/emitters/mock.d.ts.map +0 -1
- package/lib/emitters/mock.js +0 -265
- package/lib/emitters/mock.js.map +0 -1
- package/lib/emitters/operation-aliases.d.ts +0 -27
- package/lib/emitters/operation-aliases.d.ts.map +0 -1
- package/lib/emitters/operation-aliases.js +0 -150
- package/lib/emitters/operation-aliases.js.map +0 -1
- package/lib/emitters/operation-signature.d.ts +0 -24
- package/lib/emitters/operation-signature.d.ts.map +0 -1
- package/lib/emitters/operation-signature.js +0 -42
- package/lib/emitters/operation-signature.js.map +0 -1
- package/lib/emitters/operation-types.d.ts +0 -32
- package/lib/emitters/operation-types.d.ts.map +0 -1
- package/lib/emitters/operation-types.js +0 -117
- package/lib/emitters/operation-types.js.map +0 -1
- package/lib/emitters/operations.d.ts +0 -41
- package/lib/emitters/operations.d.ts.map +0 -1
- package/lib/emitters/operations.js +0 -35
- package/lib/emitters/operations.js.map +0 -1
- package/lib/emitters/pagination.d.ts.map +0 -1
- package/lib/emitters/pagination.js.map +0 -1
- package/lib/emitters/reserved-names.d.ts +0 -5
- package/lib/emitters/reserved-names.d.ts.map +0 -1
- package/lib/emitters/reserved-names.js.map +0 -1
- package/lib/emitters/response-headers.d.ts +0 -14
- package/lib/emitters/response-headers.d.ts.map +0 -1
- package/lib/emitters/response-headers.js +0 -91
- package/lib/emitters/response-headers.js.map +0 -1
- package/lib/emitters/runtime-sources.d.ts +0 -16
- package/lib/emitters/runtime-sources.d.ts.map +0 -1
- package/lib/emitters/runtime-sources.js +0 -16
- package/lib/emitters/runtime-sources.js.map +0 -1
- package/lib/emitters/sample.d.ts.map +0 -1
- package/lib/emitters/sample.js.map +0 -1
- package/lib/emitters/setup-bake.d.ts.map +0 -1
- package/lib/emitters/setup-bake.js.map +0 -1
- package/lib/emitters/sse.d.ts +0 -10
- package/lib/emitters/sse.d.ts.map +0 -1
- package/lib/emitters/sse.js +0 -46
- package/lib/emitters/sse.js.map +0 -1
- package/lib/emitters/support.d.ts +0 -18
- package/lib/emitters/support.d.ts.map +0 -1
- package/lib/emitters/support.js +0 -37
- package/lib/emitters/support.js.map +0 -1
- package/lib/emitters/swr.d.ts.map +0 -1
- package/lib/emitters/swr.js +0 -88
- package/lib/emitters/swr.js.map +0 -1
- package/lib/emitters/tanstack-query.d.ts.map +0 -1
- package/lib/emitters/tanstack-query.js.map +0 -1
- package/lib/emitters/transformers.d.ts.map +0 -1
- package/lib/emitters/transformers.js.map +0 -1
- package/lib/emitters/ts.d.ts +0 -42
- package/lib/emitters/ts.d.ts.map +0 -1
- package/lib/emitters/ts.js +0 -116
- package/lib/emitters/ts.js.map +0 -1
- package/lib/emitters/type-guards.d.ts +0 -21
- package/lib/emitters/type-guards.d.ts.map +0 -1
- package/lib/emitters/type-guards.js.map +0 -1
- package/lib/emitters/types.d.ts +0 -15
- package/lib/emitters/types.d.ts.map +0 -1
- package/lib/emitters/types.js +0 -125
- package/lib/emitters/types.js.map +0 -1
- package/lib/emitters/wrapper-support.d.ts.map +0 -1
- package/lib/emitters/wrapper-support.js +0 -127
- package/lib/emitters/wrapper-support.js.map +0 -1
- package/lib/emitters/zod.d.ts.map +0 -1
- package/lib/emitters/zod.js.map +0 -1
- package/lib/generators/anchor.d.ts +0 -9
- package/lib/generators/anchor.d.ts.map +0 -1
- package/lib/generators/anchor.js +0 -10
- package/lib/generators/anchor.js.map +0 -1
- package/lib/generators/mock.d.ts.map +0 -1
- package/lib/generators/mock.js.map +0 -1
- package/lib/generators/sdk.d.ts +0 -12
- package/lib/generators/sdk.d.ts.map +0 -1
- package/lib/generators/sdk.js +0 -26
- package/lib/generators/sdk.js.map +0 -1
- package/lib/generators/swr.d.ts.map +0 -1
- package/lib/generators/swr.js.map +0 -1
- package/lib/generators/tanstack-query.d.ts.map +0 -1
- package/lib/generators/tanstack-query.js.map +0 -1
- package/lib/generators/transformers.d.ts.map +0 -1
- package/lib/generators/transformers.js.map +0 -1
- package/lib/generators/zod.d.ts.map +0 -1
- package/lib/generators/zod.js.map +0 -1
- package/lib/runtime/auth.d.ts.map +0 -1
- package/lib/runtime/auth.js.map +0 -1
- package/lib/runtime/create-client.d.ts.map +0 -1
- package/lib/runtime/create-client.js.map +0 -1
- package/lib/runtime/errors.d.ts.map +0 -1
- package/lib/runtime/errors.js.map +0 -1
- package/lib/runtime/index.d.ts.map +0 -1
- package/lib/runtime/index.js.map +0 -1
- package/lib/runtime/multipart.d.ts.map +0 -1
- package/lib/runtime/multipart.js.map +0 -1
- package/lib/runtime/paginate.d.ts.map +0 -1
- package/lib/runtime/paginate.js.map +0 -1
- package/lib/runtime/parse.d.ts.map +0 -1
- package/lib/runtime/parse.js.map +0 -1
- package/lib/runtime/retry.d.ts.map +0 -1
- package/lib/runtime/retry.js.map +0 -1
- package/lib/runtime/send.d.ts.map +0 -1
- package/lib/runtime/send.js.map +0 -1
- package/lib/runtime/setup.d.ts.map +0 -1
- package/lib/runtime/setup.js.map +0 -1
- package/lib/runtime/sse.d.ts.map +0 -1
- package/lib/runtime/sse.js.map +0 -1
- package/lib/runtime/types.d.ts.map +0 -1
- package/lib/runtime/types.js.map +0 -1
- package/lib/runtime/url.d.ts.map +0 -1
- package/lib/runtime/url.js.map +0 -1
- /package/lib/{emitters → generators/mock}/sample.js +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/auth.d.ts +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/auth.js +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/errors.d.ts +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/errors.js +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/index.d.ts +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/index.js +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/multipart.d.ts +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/multipart.js +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/parse.d.ts +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/parse.js +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/retry.d.ts +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/retry.js +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/send.d.ts +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/send.js +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/setup.d.ts +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/setup.js +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/sse.d.ts +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/sse.js +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/types.js +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/url.d.ts +0 -0
- /package/lib/{runtime → generators/typescript/runtime}/url.js +0 -0
- /package/lib/{emitters/setup-bake.d.ts → setup-bake.d.ts} +0 -0
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
// Ejected from @redocly/client-generator@0.4.0 — the built-in "zod" generator.
|
|
2
|
+
// This file is yours: edit freely; the generated client stays machine-owned and is
|
|
3
|
+
// rebuilt by `redocly generate-client`. Newer generator versions merge in with
|
|
4
|
+
// `redocly eject-generator zod --update`.
|
|
5
|
+
// Emits Zod schemas from the IR. Each named schema becomes an
|
|
6
|
+
// `export const <Name>Schema = z.<…>;` — source-text templates mirroring the
|
|
7
|
+
// type renderer (`typescript/types.ts`) but targeting runtime validators instead of types.
|
|
8
|
+
// Operations with a JSON request or response body additionally land in the
|
|
9
|
+
// `operationSchemas` map, which powers the `zodValidation` client middleware.
|
|
10
|
+
//
|
|
11
|
+
// Only the refinement methods stable across zod 3.23 and 4 are emitted
|
|
12
|
+
// (`.min/.max/.int/.gt/.lt/.regex`); format helpers (`.email/.uuid/.url`) diverge
|
|
13
|
+
// between major versions and are deferred. Refs become `z.lazy(() => …Schema)`,
|
|
14
|
+
// which sidesteps declaration ordering and recursion uniformly.
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
allOperations,
|
|
18
|
+
type ApiModel,
|
|
19
|
+
type PropertyModel,
|
|
20
|
+
type ScalarKind,
|
|
21
|
+
type SchemaMetadata,
|
|
22
|
+
type SchemaModel,
|
|
23
|
+
} from '@redocly/client-generator';
|
|
24
|
+
import { codeLiteral, pascalCase, safeIdent } from '@redocly/client-generator/printers/typescript';
|
|
25
|
+
|
|
26
|
+
const INDENT = ' ';
|
|
27
|
+
|
|
28
|
+
/** `<Name>Schema` — the const identifier a named schema is bound to. */
|
|
29
|
+
function schemaConstName(name: string): string {
|
|
30
|
+
return `${pascalCase(name)}Schema`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type SchemaByName = ReadonlyMap<string, SchemaModel>;
|
|
34
|
+
|
|
35
|
+
const NO_SCHEMAS: SchemaByName = new Map();
|
|
36
|
+
|
|
37
|
+
/** Map an IR schema to the Zod expression (source text) that validates it. */
|
|
38
|
+
export function schemaToZodExpression(
|
|
39
|
+
schema: SchemaModel,
|
|
40
|
+
byName: SchemaByName = NO_SCHEMAS,
|
|
41
|
+
indent = ''
|
|
42
|
+
): string {
|
|
43
|
+
return withRefinements(baseExpression(schema, byName, indent), schema);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function baseExpression(schema: SchemaModel, byName: SchemaByName, indent: string): string {
|
|
47
|
+
switch (schema.kind) {
|
|
48
|
+
case 'scalar':
|
|
49
|
+
return scalarExpression(schema.scalar, schema.metadata);
|
|
50
|
+
case 'object':
|
|
51
|
+
return objectExpression(schema.properties, byName, indent);
|
|
52
|
+
case 'array':
|
|
53
|
+
return `z.array(${schemaToZodExpression(schema.items, byName, indent)})`;
|
|
54
|
+
case 'record':
|
|
55
|
+
return `z.record(z.string(), ${schemaToZodExpression(schema.value, byName, indent)})`;
|
|
56
|
+
case 'ref':
|
|
57
|
+
return `z.lazy(() => ${schemaConstName(schema.name)})`;
|
|
58
|
+
case 'literal':
|
|
59
|
+
return `z.literal(${codeLiteral(schema.value)})`;
|
|
60
|
+
case 'enum':
|
|
61
|
+
return enumExpression(schema.values);
|
|
62
|
+
case 'union':
|
|
63
|
+
return unionExpression(schema.members, byName, indent);
|
|
64
|
+
case 'intersection':
|
|
65
|
+
return schema.members
|
|
66
|
+
.map((member) => schemaToZodExpression(member, byName, indent))
|
|
67
|
+
.reduce((acc, next) => `${acc}.and(${next})`);
|
|
68
|
+
case 'null':
|
|
69
|
+
return 'z.null()';
|
|
70
|
+
case 'unknown':
|
|
71
|
+
return 'z.unknown()';
|
|
72
|
+
case 'omit':
|
|
73
|
+
return omitExpression(schema.base, schema.keys, byName, indent);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function scalarExpression(scalar: ScalarKind, metadata?: SchemaMetadata): string {
|
|
78
|
+
switch (scalar) {
|
|
79
|
+
case 'string':
|
|
80
|
+
// `format: binary` is typed as `Blob` (see typescript/types.ts); validate it as one so the
|
|
81
|
+
// zod schema agrees with the generated type instead of expecting a string.
|
|
82
|
+
return metadata?.format === 'binary' ? 'z.instanceof(Blob)' : 'z.string()';
|
|
83
|
+
case 'integer':
|
|
84
|
+
return 'z.number().int()';
|
|
85
|
+
case 'number':
|
|
86
|
+
return 'z.number()';
|
|
87
|
+
case 'boolean':
|
|
88
|
+
return 'z.boolean()';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** A bare identifier key when valid, a quoted key otherwise. */
|
|
93
|
+
function propertyKeyText(name: string): string {
|
|
94
|
+
return safeIdent(name) === name ? name : JSON.stringify(name);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** `z.object({ <key>: <expr>(.optional() when !required), … })` — multiline when non-empty. */
|
|
98
|
+
function objectExpression(
|
|
99
|
+
properties: PropertyModel[],
|
|
100
|
+
byName: SchemaByName,
|
|
101
|
+
indent: string
|
|
102
|
+
): string {
|
|
103
|
+
if (properties.length === 0) return 'z.object({})';
|
|
104
|
+
const inner = indent + INDENT;
|
|
105
|
+
const lines = properties.map((property, index) => {
|
|
106
|
+
const expr = schemaToZodExpression(property.schema, byName, inner);
|
|
107
|
+
const value = property.required ? expr : `${expr}.optional()`;
|
|
108
|
+
const comma = index === properties.length - 1 ? '' : ',';
|
|
109
|
+
return `${inner}${propertyKeyText(property.name)}: ${value}${comma}`;
|
|
110
|
+
});
|
|
111
|
+
return `z.object({\n${lines.join('\n')}\n${indent}})`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** All-string values → `z.enum([…])`; otherwise → a union of literals. */
|
|
115
|
+
function enumExpression(values: Array<string | number | boolean>): string {
|
|
116
|
+
if (values.every((value) => typeof value === 'string')) {
|
|
117
|
+
return `z.enum([${values.map((value) => JSON.stringify(value)).join(', ')}])`;
|
|
118
|
+
}
|
|
119
|
+
return `z.union([${values.map((value) => `z.literal(${codeLiteral(value)})`).join(', ')}])`;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** `z.union([…])`; a single member collapses to that member's expression. */
|
|
123
|
+
function unionExpression(members: SchemaModel[], byName: SchemaByName, indent: string): string {
|
|
124
|
+
const exprs = members.map((member) => schemaToZodExpression(member, byName, indent));
|
|
125
|
+
if (exprs.length === 1) return exprs[0];
|
|
126
|
+
return `z.union([${exprs.join(', ')}])`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* `<Base>Schema.omit({ k1: true, … })` when the base is a plain object schema.
|
|
131
|
+
* `.omit` exists only on `ZodObject` — for any other base (an `allOf` intersection,
|
|
132
|
+
* a union, …) the omission is distributed into the base's object members instead.
|
|
133
|
+
*/
|
|
134
|
+
function omitExpression(
|
|
135
|
+
base: string,
|
|
136
|
+
keys: string[],
|
|
137
|
+
byName: SchemaByName,
|
|
138
|
+
indent: string
|
|
139
|
+
): string {
|
|
140
|
+
const target = byName.get(base);
|
|
141
|
+
if (target && target.kind !== 'object') {
|
|
142
|
+
return schemaToZodExpression(applyOmit(target, keys, byName, new Set([base])), byName, indent);
|
|
143
|
+
}
|
|
144
|
+
const mask = keys.map((key) => `${propertyKeyText(key)}: true`).join(', ');
|
|
145
|
+
return `${schemaConstName(base)}.omit({ ${mask} })`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Remove `keys` from a schema that is not a plain object: objects drop the properties,
|
|
150
|
+
* union/intersection members recurse, and a ref to an object becomes `<Ref>Schema.omit`
|
|
151
|
+
* with only the keys that exist on it (zod's mask rejects unknown keys at the type
|
|
152
|
+
* level). Cycles and non-object leaves return unchanged — there is nothing to omit.
|
|
153
|
+
*/
|
|
154
|
+
function applyOmit(
|
|
155
|
+
schema: SchemaModel,
|
|
156
|
+
keys: string[],
|
|
157
|
+
byName: SchemaByName,
|
|
158
|
+
seen: Set<string>
|
|
159
|
+
): SchemaModel {
|
|
160
|
+
switch (schema.kind) {
|
|
161
|
+
case 'object':
|
|
162
|
+
return { ...schema, properties: schema.properties.filter((p) => !keys.includes(p.name)) };
|
|
163
|
+
case 'union':
|
|
164
|
+
case 'intersection':
|
|
165
|
+
return {
|
|
166
|
+
...schema,
|
|
167
|
+
members: schema.members.map((member) => applyOmit(member, keys, byName, seen)),
|
|
168
|
+
};
|
|
169
|
+
case 'ref': {
|
|
170
|
+
if (seen.has(schema.name)) return schema;
|
|
171
|
+
const target = byName.get(schema.name);
|
|
172
|
+
if (!target) return schema;
|
|
173
|
+
if (target.kind === 'object') {
|
|
174
|
+
const present = keys.filter((key) =>
|
|
175
|
+
target.properties.some((property) => property.name === key)
|
|
176
|
+
);
|
|
177
|
+
return present.length > 0 ? { kind: 'omit', base: schema.name, keys: present } : schema;
|
|
178
|
+
}
|
|
179
|
+
return applyOmit(target, keys, byName, new Set([...seen, schema.name]));
|
|
180
|
+
}
|
|
181
|
+
default:
|
|
182
|
+
return schema;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Chain the stable-subset metadata refinements onto `expr`. Order: numeric/length
|
|
188
|
+
* bounds, then `.regex` (the `.int()` for integers is already on the base).
|
|
189
|
+
* `.optional()` is NOT applied here — optionality is a property-level concern
|
|
190
|
+
* handled in `objectExpression`, so a top-level schema is never spuriously optional.
|
|
191
|
+
*/
|
|
192
|
+
function withRefinements(expr: string, schema: SchemaModel): string {
|
|
193
|
+
const m = schema.metadata;
|
|
194
|
+
if (!m) return expr;
|
|
195
|
+
let out = expr;
|
|
196
|
+
if (schema.kind === 'scalar' && schema.scalar === 'string') {
|
|
197
|
+
if (m.minLength !== undefined) out = `${out}.min(${m.minLength})`;
|
|
198
|
+
if (m.maxLength !== undefined) out = `${out}.max(${m.maxLength})`;
|
|
199
|
+
if (m.pattern !== undefined) out = `${out}.regex(new RegExp(${JSON.stringify(m.pattern)}))`;
|
|
200
|
+
}
|
|
201
|
+
if (schema.kind === 'scalar' && (schema.scalar === 'number' || schema.scalar === 'integer')) {
|
|
202
|
+
if (m.minimum !== undefined) out = `${out}.min(${m.minimum})`;
|
|
203
|
+
if (m.maximum !== undefined) out = `${out}.max(${m.maximum})`;
|
|
204
|
+
if (m.exclusiveMinimum !== undefined) out = `${out}.gt(${m.exclusiveMinimum})`;
|
|
205
|
+
if (m.exclusiveMaximum !== undefined) out = `${out}.lt(${m.exclusiveMaximum})`;
|
|
206
|
+
}
|
|
207
|
+
if (schema.kind === 'array') {
|
|
208
|
+
if (m.minItems !== undefined) out = `${out}.min(${m.minItems})`;
|
|
209
|
+
if (m.maxItems !== undefined) out = `${out}.max(${m.maxItems})`;
|
|
210
|
+
}
|
|
211
|
+
return out;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* `<opName>: { request?: <expr>, response?: <expr> }` for every non-SSE operation with a
|
|
216
|
+
* JSON request or response body — the operation's validators, keyed by the same id the
|
|
217
|
+
* middleware sees at runtime (`ctx.operation.id`). SSE, binary, text, and void bodies
|
|
218
|
+
* have no JSON payload to validate and are skipped.
|
|
219
|
+
*/
|
|
220
|
+
type OperationSchemaEntry = { name: string; request?: string; response?: string };
|
|
221
|
+
|
|
222
|
+
function operationSchemaEntries(model: ApiModel, byName: SchemaByName): OperationSchemaEntry[] {
|
|
223
|
+
const entries: OperationSchemaEntry[] = [];
|
|
224
|
+
for (const op of allOperations(model.services)) {
|
|
225
|
+
if (op.sse !== undefined) continue;
|
|
226
|
+
const requestBody = op.requestBody;
|
|
227
|
+
const request =
|
|
228
|
+
requestBody && requestBody.contentType.toLowerCase().includes('json')
|
|
229
|
+
? schemaToZodExpression(requestBody.schema, byName, INDENT)
|
|
230
|
+
: undefined;
|
|
231
|
+
const jsonResponse = op.successResponses.find((response) =>
|
|
232
|
+
response.contentType.toLowerCase().includes('json')
|
|
233
|
+
);
|
|
234
|
+
const response = jsonResponse
|
|
235
|
+
? schemaToZodExpression(jsonResponse.schema, byName, INDENT)
|
|
236
|
+
: undefined;
|
|
237
|
+
if (!request && !response) continue;
|
|
238
|
+
// The SPEC operationId — the middleware looks entries up by `ctx.operation.id`,
|
|
239
|
+
// which stays the spec id even when the emitted function name was renamed.
|
|
240
|
+
entries.push({ name: op.specName ?? op.name, request, response });
|
|
241
|
+
}
|
|
242
|
+
return entries;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function operationSchemasBlock(entries: OperationSchemaEntry[]): string {
|
|
246
|
+
// The explicit `z.ZodType` annotation keeps the declaration-emit size proportional to
|
|
247
|
+
// the operation count: the inferred type would serialize every schema's zod generics
|
|
248
|
+
// and overflow tsc's limit (TS7056) on large APIs under `declaration: true`.
|
|
249
|
+
const typeLines = entries.flatMap((entry) => [
|
|
250
|
+
`${INDENT}${propertyKeyText(entry.name)}: {`,
|
|
251
|
+
...(entry.request ? [`${INDENT}${INDENT}request: z.ZodType;`] : []),
|
|
252
|
+
...(entry.response ? [`${INDENT}${INDENT}response: z.ZodType;`] : []),
|
|
253
|
+
`${INDENT}};`,
|
|
254
|
+
]);
|
|
255
|
+
const valueLines = entries.map((entry, index) => {
|
|
256
|
+
const fields = [
|
|
257
|
+
...(entry.request ? [`request: ${entry.request}`] : []),
|
|
258
|
+
...(entry.response ? [`response: ${entry.response}`] : []),
|
|
259
|
+
].join(', ');
|
|
260
|
+
const comma = index === entries.length - 1 ? '' : ',';
|
|
261
|
+
return `${INDENT}${propertyKeyText(entry.name)}: { ${fields} }${comma}`;
|
|
262
|
+
});
|
|
263
|
+
return [
|
|
264
|
+
'/**',
|
|
265
|
+
' * Request/response validators by operationId — powers `zodValidation`, or import one directly.',
|
|
266
|
+
' */',
|
|
267
|
+
'export const operationSchemas: {',
|
|
268
|
+
...typeLines,
|
|
269
|
+
'} = {',
|
|
270
|
+
...valueLines,
|
|
271
|
+
'};',
|
|
272
|
+
].join('\n');
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// The validation middleware, spliced verbatim after the schemas (matches the printer's
|
|
276
|
+
// double-quote/4-space style). Structurally compatible with the client's `Middleware`
|
|
277
|
+
// without importing it, so the zod module keeps its single `zod` dependency.
|
|
278
|
+
const VALIDATION_SUPPORT = `/** \`request\`/\`response\` validators for one operation (an absent side is not validated). */
|
|
279
|
+
export type OperationSchemaSet = { request?: z.ZodType; response?: z.ZodType };
|
|
280
|
+
|
|
281
|
+
const schemaIndex: Partial<Record<string, OperationSchemaSet>> = operationSchemas;
|
|
282
|
+
|
|
283
|
+
/** One flattened validation problem: the full nested path and a short preview of the value. */
|
|
284
|
+
export type ZodViolation = { path: string; message: string; received: string };
|
|
285
|
+
|
|
286
|
+
/** A request or response payload failed validation. Requests throw it; response handling is configurable. */
|
|
287
|
+
export class ZodValidationError extends Error {
|
|
288
|
+
// Declared and assigned in the body, NOT as constructor parameter properties: those
|
|
289
|
+
// need a transform, so they break \`node --experimental-strip-types\` for anything
|
|
290
|
+
// importing this module (the generated CLI runs that way).
|
|
291
|
+
readonly operationId: string;
|
|
292
|
+
readonly direction: "request" | "response";
|
|
293
|
+
readonly issues: z.ZodError["issues"];
|
|
294
|
+
readonly violations: ZodViolation[];
|
|
295
|
+
|
|
296
|
+
constructor(
|
|
297
|
+
operationId: string,
|
|
298
|
+
direction: "request" | "response",
|
|
299
|
+
issues: z.ZodError["issues"],
|
|
300
|
+
violations: ZodViolation[]
|
|
301
|
+
) {
|
|
302
|
+
const detail = violations
|
|
303
|
+
.slice(0, 5)
|
|
304
|
+
.map((violation) => \`\${violation.path || "(root)"}: \${violation.message} (received \${violation.received})\`)
|
|
305
|
+
.join("; ");
|
|
306
|
+
const more = violations.length > 5 ? \`; …and \${violations.length - 5} more\` : "";
|
|
307
|
+
super(\`\${direction === "request" ? "Request" : "Response"} validation failed for operation "\${operationId}": \${detail}\${more}\`);
|
|
308
|
+
this.operationId = operationId;
|
|
309
|
+
this.direction = direction;
|
|
310
|
+
this.issues = issues;
|
|
311
|
+
this.violations = violations;
|
|
312
|
+
this.name = "ZodValidationError";
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Flatten zod issues into leaf violations. Union branches (zod 3 \`unionErrors\`, zod 4
|
|
317
|
+
// nested \`errors\`) are recursed into, so the message names the actual failing fields
|
|
318
|
+
// instead of just the union root ("Invalid input").
|
|
319
|
+
function flattenIssues(
|
|
320
|
+
issues: z.ZodError["issues"],
|
|
321
|
+
value: unknown,
|
|
322
|
+
base: PropertyKey[] = []
|
|
323
|
+
): ZodViolation[] {
|
|
324
|
+
const violations: ZodViolation[] = [];
|
|
325
|
+
for (const issue of issues) {
|
|
326
|
+
const path = [...base, ...issue.path];
|
|
327
|
+
const nested = nestedIssueLists(issue);
|
|
328
|
+
if (nested.length > 0) {
|
|
329
|
+
for (const sub of nested) violations.push(...flattenIssues(sub, value, path));
|
|
330
|
+
} else {
|
|
331
|
+
violations.push({
|
|
332
|
+
path: path.map(String).join("."),
|
|
333
|
+
message: issue.message,
|
|
334
|
+
received: preview(valueAt(value, path)),
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return violations;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/** The nested issue lists of a union-ish issue, across zod 3 (\`unionErrors\`) and zod 4 (\`errors\`). */
|
|
342
|
+
function nestedIssueLists(issue: unknown): Array<z.ZodError["issues"]> {
|
|
343
|
+
const candidate = issue as {
|
|
344
|
+
unionErrors?: Array<{ issues: z.ZodError["issues"] }>;
|
|
345
|
+
errors?: Array<z.ZodError["issues"]>;
|
|
346
|
+
};
|
|
347
|
+
if (Array.isArray(candidate.unionErrors)) return candidate.unionErrors.map((error) => error.issues);
|
|
348
|
+
if (Array.isArray(candidate.errors)) return candidate.errors;
|
|
349
|
+
return [];
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function valueAt(value: unknown, path: PropertyKey[]): unknown {
|
|
353
|
+
let current = value;
|
|
354
|
+
for (const key of path) {
|
|
355
|
+
if (current === null || typeof current !== "object") return undefined;
|
|
356
|
+
current = (current as Record<PropertyKey, unknown>)[key];
|
|
357
|
+
}
|
|
358
|
+
return current;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/** A short single-line preview of the offending value. NOTE: validation output can surface
|
|
362
|
+
* payload data — route \`onViolation\` to a scrubbed logger when responses may carry secrets. */
|
|
363
|
+
function preview(value: unknown): string {
|
|
364
|
+
let text: string;
|
|
365
|
+
try {
|
|
366
|
+
text = JSON.stringify(value) ?? String(value);
|
|
367
|
+
} catch {
|
|
368
|
+
text = String(value);
|
|
369
|
+
}
|
|
370
|
+
return text.length > 80 ? \`\${text.slice(0, 77)}…\` : text;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export type ZodValidationOptions = {
|
|
374
|
+
/** Validate request bodies before any network call; a failure THROWS (it is the caller's own bug). Default: true. */
|
|
375
|
+
request?: boolean;
|
|
376
|
+
/** Replace the outgoing body with the parsed result, dropping keys the schema does not declare
|
|
377
|
+
* (for strict-DTO servers that 400 on excess properties). Runs request validation. Default: false. */
|
|
378
|
+
stripRequestBodies?: boolean;
|
|
379
|
+
/** Response drift handling: \`"warn"\` (default) reports via \`onViolation\` and lets the call
|
|
380
|
+
* succeed — a server drifting from its description should not crash the consumer;
|
|
381
|
+
* \`"throw"\` fails the call (even on result-mode clients); \`false\` skips response validation. */
|
|
382
|
+
response?: "warn" | "throw" | false;
|
|
383
|
+
/** Sink for \`"warn"\` mode. Default: \`console.warn\` with the error message. */
|
|
384
|
+
onViolation?: (error: ZodValidationError) => void;
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Schema-validation middleware for the generated client: \`use(zodValidation())\`.
|
|
389
|
+
* Request bodies are validated before any network call and throw on failure; successful
|
|
390
|
+
* JSON responses are validated against the operation's response schema and WARN by
|
|
391
|
+
* default (see \`ZodValidationOptions.response\`). Operations without a schema pass
|
|
392
|
+
* through untouched. Payloads are never mutated unless \`stripRequestBodies\` is set.
|
|
393
|
+
*/
|
|
394
|
+
export function zodValidation(options: ZodValidationOptions = {}) {
|
|
395
|
+
const { request = true, stripRequestBodies = false, response = "warn", onViolation } = options;
|
|
396
|
+
const report = onViolation ?? ((error: ZodValidationError) => console.warn(error.message));
|
|
397
|
+
return {
|
|
398
|
+
onRequest(context: { body?: unknown; operation: { id: string } }): void {
|
|
399
|
+
if ((!request && !stripRequestBodies) || context.body === undefined) return;
|
|
400
|
+
const schema = schemaIndex[context.operation.id]?.request;
|
|
401
|
+
if (!schema) return;
|
|
402
|
+
const result = schema.safeParse(context.body);
|
|
403
|
+
if (!result.success) {
|
|
404
|
+
throw new ZodValidationError(
|
|
405
|
+
context.operation.id,
|
|
406
|
+
"request",
|
|
407
|
+
result.error.issues,
|
|
408
|
+
flattenIssues(result.error.issues, context.body)
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
// zod object schemas drop undeclared keys during parsing, so the parsed value
|
|
412
|
+
// IS the declared shape (intersections keep their own zod semantics).
|
|
413
|
+
if (stripRequestBodies) context.body = result.data;
|
|
414
|
+
},
|
|
415
|
+
async onResponse(incoming: Response, context: { operation: { id: string } }): Promise<void> {
|
|
416
|
+
if (response === false || !incoming.ok) return;
|
|
417
|
+
const schema = schemaIndex[context.operation.id]?.response;
|
|
418
|
+
if (!schema) return;
|
|
419
|
+
const contentType = (incoming.headers.get("content-type") ?? "").toLowerCase();
|
|
420
|
+
if (!contentType.includes("json")) return;
|
|
421
|
+
const payload: unknown = await incoming.clone().json();
|
|
422
|
+
const result = schema.safeParse(payload);
|
|
423
|
+
if (!result.success) {
|
|
424
|
+
const error = new ZodValidationError(
|
|
425
|
+
context.operation.id,
|
|
426
|
+
"response",
|
|
427
|
+
result.error.issues,
|
|
428
|
+
flattenIssues(result.error.issues, payload)
|
|
429
|
+
);
|
|
430
|
+
if (response === "throw") throw error;
|
|
431
|
+
report(error);
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
};
|
|
435
|
+
}`;
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Render the full zod module source: the component schemas, then — when any operation
|
|
439
|
+
* has a JSON body — the `operationSchemas` map and the `zodValidation` middleware.
|
|
440
|
+
* `''` when there is nothing to emit.
|
|
441
|
+
*/
|
|
442
|
+
export function renderZodModule(model: ApiModel): string {
|
|
443
|
+
const byName: SchemaByName = new Map(model.schemas.map((named) => [named.name, named.schema]));
|
|
444
|
+
const entries = operationSchemaEntries(model, byName);
|
|
445
|
+
if (model.schemas.length === 0 && entries.length === 0) return '';
|
|
446
|
+
const blocks = [
|
|
447
|
+
'import { z } from "zod";',
|
|
448
|
+
...model.schemas.map(
|
|
449
|
+
(named) =>
|
|
450
|
+
`export const ${schemaConstName(named.name)} = ${schemaToZodExpression(named.schema, byName)};`
|
|
451
|
+
),
|
|
452
|
+
];
|
|
453
|
+
if (entries.length === 0) return blocks.join('\n\n');
|
|
454
|
+
blocks.push(operationSchemasBlock(entries));
|
|
455
|
+
return `${blocks.join('\n\n')}\n${VALIDATION_SUPPORT}\n`;
|
|
456
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cli-generator
|
|
3
|
+
description: Design of the ejected Redocly `cli` client generator. Read it, and update it, before changing generators/cli/.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# The `cli` generator — its skill
|
|
7
|
+
|
|
8
|
+
This file is the DESIGN of your ejected `cli` generator (`generators/cli/`):
|
|
9
|
+
**to change the generator, edit this skill first, then make the code match it** — a diff
|
|
10
|
+
to `generators/cli/` that has no covering sentence here is incomplete.
|
|
11
|
+
|
|
12
|
+
## What it emits
|
|
13
|
+
|
|
14
|
+
A bin-ready `<stem>.cli.ts`: one command per operation over the sdk's instance client,
|
|
15
|
+
with `--help`, a `schema <op>` introspection command, and `--dry-run`.
|
|
16
|
+
|
|
17
|
+
With `client.docs` (or `--docs`), the `docs` hook also writes `<stem>.cli.md`: the usage
|
|
18
|
+
line, the global flags, the credential variables, the exit-code table, and one section per
|
|
19
|
+
command with its positionals and flags.
|
|
20
|
+
|
|
21
|
+
## Design decisions that must hold
|
|
22
|
+
|
|
23
|
+
- **Argument shape:** path params positional, query params typed `--kebab-name` flags,
|
|
24
|
+
JSON bodies via `--json '<json>' | @file | @-` (stdin).
|
|
25
|
+
- **Help is the whole interface.** A flag that exists but isn't in `--help` doesn't exist
|
|
26
|
+
to the user, so the top-level help carries a `Global flags:` section (`--server-url`,
|
|
27
|
+
`--format`, `--dry-run`, `--page-all`, `--output`, `--token`, `--json`) plus the
|
|
28
|
+
credential environment variables. Descriptions are collapsed to ONE line — an OpenAPI
|
|
29
|
+
description with newlines otherwise breaks the alignment of every following flag. The
|
|
30
|
+
footer names the form that actually works for a grouped API
|
|
31
|
+
(`<bin> <group> <command> --help`).
|
|
32
|
+
- **Commands are addressable the way a shell allows.** A group slug is kebab-cased so a
|
|
33
|
+
multi-word OpenAPI tag can be typed without quoting, while help shows the original tag.
|
|
34
|
+
A bare operationId resolves to its grouped command when unambiguous.
|
|
35
|
+
- **Exit codes are a contract:** 0 ok, 1 API error, 2 auth, 3 validation, 4 usage.
|
|
36
|
+
Errors print ONE JSON object to stderr so stdout stays pipeable.
|
|
37
|
+
- **The CLI names itself from `process.argv[1]`.** Only the operator's `bin` field decides
|
|
38
|
+
what the command is called, so help reads the invoked name back instead of printing a
|
|
39
|
+
name from generation that may not exist on the machine.
|
|
40
|
+
- **Credentials come from the environment** — `wiring.envPrefix`, the constant-cased output
|
|
41
|
+
stem (`CLIENT_TOKEN`), which a composed entry sets per api alias — or explicit flags;
|
|
42
|
+
`--dry-run` prints the prepared request with credentials REDACTED. The prefix is fixed at
|
|
43
|
+
generation on purpose: a renamed binary must keep reading the variables a published CLI
|
|
44
|
+
already documents. Help lists only the credentials the description declares, and an
|
|
45
|
+
unusable `--token` is a usage error, never silently dropped.
|
|
46
|
+
- **Validation is on by default.** The generator declares `requires: ['typescript', 'zod']` and
|
|
47
|
+
the pipeline pulls prerequisites in automatically, so `--generator cli` alone produces a
|
|
48
|
+
validating CLI — a user shouldn't have to know which other generator provides it. The
|
|
49
|
+
consequence is a zod peer dependency at run time, which the docs state.
|
|
50
|
+
- Throw-mode only — the exit-code mapping reads thrown `ApiError`s.
|
|
51
|
+
- **Runs under `node --experimental-strip-types` with no build step**, including the
|
|
52
|
+
modules it imports (the sdk and the zod module). Anything emitted must be erasable
|
|
53
|
+
TypeScript; a parameter property anywhere in that import graph breaks the zero-build
|
|
54
|
+
runner.
|
|
55
|
+
- **The generated module is a library as well as a binary.** It exports `COMMANDS`,
|
|
56
|
+
`wiring`, and `run`, and self-executes only when it is the process entry — a REALPATH
|
|
57
|
+
comparison of `import.meta.url` against `argv[1]`, because some runners resolve
|
|
58
|
+
symlinks in one but not the other (macOS temp dirs, installed bin symlinks), and a
|
|
59
|
+
plain URL comparison silently runs nothing. `import.meta.main` would be cleaner but is
|
|
60
|
+
absent from our Node floors. Importing the module must be side-effect-safe:
|
|
61
|
+
module-level wiring (zod validation) touches only the module's OWN client, never a
|
|
62
|
+
global.
|
|
63
|
+
- **Behavior that is not in the description is composed, never generated.** A custom
|
|
64
|
+
command (`login`, anything) is the operation-command data shape plus a `handler`, so it
|
|
65
|
+
inherits help, parsing, `schema`, and the exit-code contract; `runCli` dispatches it
|
|
66
|
+
instead of the client. The generator itself never learns what such a command does —
|
|
67
|
+
credentials files, login flows, and profiles are user land (or a future satellite),
|
|
68
|
+
by design.
|
|
69
|
+
- **One binary can span several descriptions.** `runCli` also accepts sources — each a
|
|
70
|
+
command list plus, optionally, its OWN wiring (own base URL, schemes, credentials)
|
|
71
|
+
behind a namespace, so colliding operationIds across descriptions are simply different
|
|
72
|
+
commands (`cafe shop createOrder`, `cafe kitchen createOrder`). A namespace-less source
|
|
73
|
+
puts commands at the root (`cafe login`); a root command whose name matches a namespace
|
|
74
|
+
is rejected at startup, never shadowed. A source WITHOUT wiring inherits the first
|
|
75
|
+
wired source's — a root `login` shares the composed binary's identity, which is the
|
|
76
|
+
whole point of composing it there.
|
|
77
|
+
- **The composed entry is generated, not hand-rolled.** A top-level `client.cliOutput`
|
|
78
|
+
makes `redocly generate-client` (no api argument) emit one entry over every api that
|
|
79
|
+
selected `cli`: the namespace is the api ALIAS from `apis:`, and the credential prefix
|
|
80
|
+
defaults to `<BINNAME>_<ALIAS>` (`CAFE_SHOP_TOKEN`) via `wiring.envPrefix` — which
|
|
81
|
+
exists precisely so the display name and the credential prefix can differ. The composed
|
|
82
|
+
entry exports its `SOURCES` so an adopter layers custom commands around it without
|
|
83
|
+
editing a generated file. Without `cliOutput`, nothing changes.
|
|
84
|
+
|
|
85
|
+
- **The CLI documents itself.** The page is this generator's `docs` hook, not a separate
|
|
86
|
+
generator: nothing else knows this tool's commands, and a reader who ejects `cli` gets
|
|
87
|
+
the page layout with it. The page renders from `commandData` — the same table `runCli`
|
|
88
|
+
dispatches on — so it cannot describe a tool other than the one beside it. A capability
|
|
89
|
+
reaches the page only by being in that table. The page is Markdown that survives a
|
|
90
|
+
linter (ATX headings, a blank line around every block, no hard tabs, one sentence per
|
|
91
|
+
line) and it escapes what descriptions contain, because a summary is arbitrary text.
|
|
92
|
+
|
|
93
|
+
## The stage files
|
|
94
|
+
|
|
95
|
+
`render.ts` derives `commandData` from the IR and renders the module and the composed
|
|
96
|
+
entry; `docs.ts` renders the reference page from the same command table;
|
|
97
|
+
`engine-source.ts` supplies the cli engine's source text — the engine itself (`runCli`,
|
|
98
|
+
the parser, help, dispatch) ships inside the package and arrives through
|
|
99
|
+
`@redocly/client-generator/runtime-sources` (in this repo it lives in `runtime/cli.ts`
|
|
100
|
+
beside these files). `index.ts` is the entry. The sdk calling convention comes from
|
|
101
|
+
`@redocly/client-generator/contracts/typescript`.
|
|
102
|
+
|
|
103
|
+
## Ejecting it
|
|
104
|
+
|
|
105
|
+
`redocly eject-generator cli` copies this generator's TypeScript source folder to
|
|
106
|
+
`generators/cli/`, exactly as we wrote it, importing `@redocly/client-generator`,
|
|
107
|
+
`@redocly/client-generator/contracts/typescript`,
|
|
108
|
+
`@redocly/client-generator/runtime-sources` (the embedded cli engine), and
|
|
109
|
+
`@redocly/openapi-core`. Running a `.ts` generator uses Node's type stripping (Node
|
|
110
|
+
22.18, 23.6, or newer); newer built-in versions merge in per file with `--update`. Change
|
|
111
|
+
the command surface, the help layout, or the exit-code mapping, and regenerate. The exit
|
|
112
|
+
codes are a contract for scripts, so change them only deliberately.
|
|
113
|
+
|
|
114
|
+
## The modify loop
|
|
115
|
+
|
|
116
|
+
1. Edit this skill: state the new behavior or decision.
|
|
117
|
+
2. Make `generators/cli/` match it.
|
|
118
|
+
3. Run `redocly generate-client` and inspect the `git diff` of the generated output —
|
|
119
|
+
generated files are never hand-edited.
|
|
120
|
+
|
|
121
|
+
Newer built-in versions merge in with `redocly eject-generator cli --update`.
|