@redocly/client-generator 0.3.7 → 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 @@
|
|
|
1
|
+
{"version":3,"file":"typescript.js","sourceRoot":"","sources":["../../src/printers/typescript.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Module-scope identifiers every package-mode sdk file emits or imports — never renamed. */
|
|
2
|
+
export declare const WIRING_NAMES: string[];
|
|
3
|
+
/** Every name the generated modules reserve: wiring + satellite + globals + runtime
|
|
4
|
+
* declarations. The runtime layer is precomputed at prepare time
|
|
5
|
+
* (`RUNTIME_DECLARED_NAMES`), so building this set never needs the TS parser —
|
|
6
|
+
* keeping the pipeline `typescript`-free for non-TS generator selections. */
|
|
7
|
+
export declare function reservedModuleNames(): Set<string>;
|
|
8
|
+
//# sourceMappingURL=reserved-names.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reserved-names.d.ts","sourceRoot":"","sources":["../src/reserved-names.ts"],"names":[],"mappings":"AAYA,6FAA6F;AAC7F,eAAO,MAAM,YAAY,UA0BxB,CAAC;AAgFF;;;6EAG6E;AAC7E,wBAAgB,mBAAmB,IAAI,GAAG,CAAC,MAAM,CAAC,CAUjD"}
|
|
@@ -4,11 +4,10 @@
|
|
|
4
4
|
// import or declare, the platform globals the emitted code references bare (a
|
|
5
5
|
// same-named schema TYPE would shadow them), and every top-level declaration of the
|
|
6
6
|
// runtime sources (in embed mode ALL of them — even module-local helpers — share
|
|
7
|
-
// the module scope with the generated code). The runtime layer is
|
|
8
|
-
//
|
|
9
|
-
// drift.
|
|
10
|
-
import {
|
|
11
|
-
import { parseStatements, ts } from './ts.js';
|
|
7
|
+
// the module scope with the generated code). The runtime layer is precomputed from
|
|
8
|
+
// the runtime sources at prepare time (`RUNTIME_DECLARED_NAMES`), so it tracks the
|
|
9
|
+
// real runtime with no hand-maintained list to drift.
|
|
10
|
+
import { RUNTIME_DECLARED_NAMES } from './runtime-sources/typescript.js';
|
|
12
11
|
/** Module-scope identifiers every package-mode sdk file emits or imports — never renamed. */
|
|
13
12
|
export const WIRING_NAMES = [
|
|
14
13
|
'client',
|
|
@@ -65,6 +64,7 @@ const GLOBAL_NAMES = [
|
|
|
65
64
|
'ArrayBuffer',
|
|
66
65
|
'ArrayBufferView',
|
|
67
66
|
'AsyncGenerator',
|
|
67
|
+
'AsyncIterable',
|
|
68
68
|
'Blob',
|
|
69
69
|
'BodyInit',
|
|
70
70
|
'Boolean',
|
|
@@ -96,6 +96,7 @@ const GLOBAL_NAMES = [
|
|
|
96
96
|
'TextDecoder',
|
|
97
97
|
'TextEncoder',
|
|
98
98
|
'TypeError',
|
|
99
|
+
'Uint8Array',
|
|
99
100
|
'URL',
|
|
100
101
|
'URLSearchParams',
|
|
101
102
|
'btoa',
|
|
@@ -110,31 +111,19 @@ const GLOBAL_NAMES = [
|
|
|
110
111
|
'undefined',
|
|
111
112
|
];
|
|
112
113
|
let cached;
|
|
113
|
-
/** Every name the generated modules reserve: wiring + satellite + globals + runtime
|
|
114
|
+
/** Every name the generated modules reserve: wiring + satellite + globals + runtime
|
|
115
|
+
* declarations. The runtime layer is precomputed at prepare time
|
|
116
|
+
* (`RUNTIME_DECLARED_NAMES`), so building this set never needs the TS parser —
|
|
117
|
+
* keeping the pipeline `typescript`-free for non-TS generator selections. */
|
|
114
118
|
export function reservedModuleNames() {
|
|
115
119
|
if (cached === undefined) {
|
|
116
|
-
cached = new Set([
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
cached = new Set([
|
|
121
|
+
...WIRING_NAMES,
|
|
122
|
+
...SATELLITE_NAMES,
|
|
123
|
+
...GLOBAL_NAMES,
|
|
124
|
+
...RUNTIME_DECLARED_NAMES,
|
|
125
|
+
]);
|
|
121
126
|
}
|
|
122
127
|
return cached;
|
|
123
128
|
}
|
|
124
|
-
function collectDeclaredName(statement, into) {
|
|
125
|
-
if ((ts.isFunctionDeclaration(statement) ||
|
|
126
|
-
ts.isClassDeclaration(statement) ||
|
|
127
|
-
ts.isInterfaceDeclaration(statement) ||
|
|
128
|
-
ts.isTypeAliasDeclaration(statement) ||
|
|
129
|
-
ts.isEnumDeclaration(statement)) &&
|
|
130
|
-
statement.name !== undefined) {
|
|
131
|
-
into.add(statement.name.text);
|
|
132
|
-
}
|
|
133
|
-
else if (ts.isVariableStatement(statement)) {
|
|
134
|
-
for (const declaration of statement.declarationList.declarations) {
|
|
135
|
-
if (ts.isIdentifier(declaration.name))
|
|
136
|
-
into.add(declaration.name.text);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
129
|
//# sourceMappingURL=reserved-names.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reserved-names.js","sourceRoot":"","sources":["../src/reserved-names.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,oFAAoF;AACpF,oFAAoF;AACpF,8EAA8E;AAC9E,oFAAoF;AACpF,iFAAiF;AACjF,mFAAmF;AACnF,mFAAmF;AACnF,sDAAsD;AAEtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,6FAA6F;AAC7F,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,QAAQ;IACR,YAAY;IACZ,KAAK;IACL,aAAa;IACb,eAAe;IACf,cAAc;IACd,cAAc;IACd,YAAY;IACZ,UAAU;IACV,cAAc;IACd,WAAW;IACX,KAAK;IACL,MAAM;IACN,gBAAgB;IAChB,cAAc;IACd,gBAAgB;IAChB,YAAY;IACZ,YAAY;IACZ,qBAAqB;IACrB,iBAAiB;IACjB,QAAQ;IACR,UAAU;IACV,gBAAgB;IAChB,eAAe;IACf,gBAAgB;CACjB,CAAC;AAEF,gFAAgF;AAChF,mFAAmF;AACnF,8BAA8B;AAC9B,MAAM,eAAe,GAAG;IACtB,GAAG;IACH,MAAM;IACN,cAAc;IACd,UAAU;IACV,OAAO;IACP,cAAc;IACd,QAAQ;IACR,gBAAgB;IAChB,YAAY;CACb,CAAC;AAEF,uFAAuF;AACvF,uFAAuF;AACvF,mFAAmF;AACnF,uFAAuF;AACvF,mFAAmF;AACnF,uFAAuF;AACvF,kFAAkF;AAClF,oFAAoF;AACpF,MAAM,YAAY,GAAG;IACnB,aAAa;IACb,OAAO;IACP,aAAa;IACb,iBAAiB;IACjB,gBAAgB;IAChB,eAAe;IACf,MAAM;IACN,UAAU;IACV,SAAS;IACT,cAAc;IACd,MAAM;IACN,OAAO;IACP,SAAS;IACT,UAAU;IACV,SAAS;IACT,aAAa;IACb,MAAM;IACN,KAAK;IACL,MAAM;IACN,aAAa;IACb,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,SAAS;IACT,SAAS;IACT,gBAAgB;IAChB,QAAQ;IACR,QAAQ;IACR,iBAAiB;IACjB,SAAS;IACT,aAAa;IACb,UAAU;IACV,KAAK;IACL,QAAQ;IACR,aAAa;IACb,aAAa;IACb,WAAW;IACX,YAAY;IACZ,KAAK;IACL,iBAAiB;IACjB,MAAM;IACN,cAAc;IACd,QAAQ;IACR,oBAAoB;IACpB,UAAU;IACV,oBAAoB;IACpB,OAAO;IACP,YAAY;IACZ,YAAY;IACZ,WAAW;CACZ,CAAC;AAEF,IAAI,MAA+B,CAAC;AAEpC;;;6EAG6E;AAC7E,MAAM,UAAU,mBAAmB;IACjC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,GAAG,IAAI,GAAG,CAAC;YACf,GAAG,YAAY;YACf,GAAG,eAAe;YAClB,GAAG,YAAY;YACf,GAAG,sBAAsB;SAC1B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1,5 +1,59 @@
|
|
|
1
|
-
|
|
2
|
-
export type
|
|
1
|
+
/** Backoff shape: 'fixed' = constant delay; 'exponential' = doubling per attempt. */
|
|
2
|
+
export type RetryStrategy = 'fixed' | 'exponential';
|
|
3
|
+
/**
|
|
4
|
+
* The operation's identity, exposed to middleware for targeting (`ctx.operation`).
|
|
5
|
+
* Generated clients instantiate the type parameters with the spec's literal unions
|
|
6
|
+
* (`OperationId`/`OperationPath`/`OperationTag`) so a misspelled operation id in a
|
|
7
|
+
* middleware comparison fails to compile; the string defaults keep every
|
|
8
|
+
* spec-independent consumer (`runtime-contract.ts`, the runtime internals) working
|
|
9
|
+
* with the base shape. `tags` stays mutable (`Tag[]`) so setup-contract types
|
|
10
|
+
* (byte-locked to generated output) remain assignable through middleware callbacks.
|
|
11
|
+
*/
|
|
12
|
+
export type OperationContext<Id extends string = string, Path extends string = string, Tag extends string = string> = {
|
|
13
|
+
id: Id;
|
|
14
|
+
path: Path;
|
|
15
|
+
tags: Tag[];
|
|
16
|
+
};
|
|
17
|
+
/** The mutable request context threaded through the middleware chain. */
|
|
18
|
+
export type RequestContext<Op extends OperationContext = OperationContext> = {
|
|
19
|
+
url: string;
|
|
20
|
+
method: string;
|
|
21
|
+
headers: Record<string, string>;
|
|
22
|
+
body?: unknown;
|
|
23
|
+
operation: Op;
|
|
24
|
+
};
|
|
25
|
+
/** The failed attempt handed to a custom `retryOn`: exactly one of `response`/`error` is set. */
|
|
26
|
+
export type RetryContext<Op extends OperationContext = OperationContext> = {
|
|
27
|
+
attempt: number;
|
|
28
|
+
request: RequestContext<Op>;
|
|
29
|
+
response?: Response;
|
|
30
|
+
error?: unknown;
|
|
31
|
+
};
|
|
32
|
+
/** Opt-in retry policy; a per-call override merges field-by-field over the config policy. */
|
|
33
|
+
export type RetryConfig<Op extends OperationContext = OperationContext> = {
|
|
34
|
+
retries?: number;
|
|
35
|
+
retryDelay?: number;
|
|
36
|
+
retryStrategy?: RetryStrategy;
|
|
37
|
+
jitter?: boolean;
|
|
38
|
+
retryOn?: (ctx: RetryContext<Op>) => boolean | Promise<boolean>;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Structural stand-in for the runtime's ApiError so this module stays import-free
|
|
42
|
+
* (pure types); the real `ApiError` class is assignable to it.
|
|
43
|
+
*/
|
|
44
|
+
export type ApiErrorLike = globalThis.Error & {
|
|
45
|
+
url: string;
|
|
46
|
+
status: number;
|
|
47
|
+
statusText: string;
|
|
48
|
+
body: unknown;
|
|
49
|
+
};
|
|
50
|
+
/** One interceptor: any subset of the three hooks. */
|
|
51
|
+
export type Middleware<Op extends OperationContext = OperationContext> = {
|
|
52
|
+
onRequest?: (ctx: RequestContext<Op>) => void | Promise<void>;
|
|
53
|
+
onResponse?: (response: Response, ctx: RequestContext<Op>) => Response | void | Promise<Response | void>;
|
|
54
|
+
/** Throw mode only: may map/replace the error. */
|
|
55
|
+
onError?: (error: ApiErrorLike, ctx: RequestContext<Op>) => globalThis.Error | Promise<globalThis.Error>;
|
|
56
|
+
};
|
|
3
57
|
/**
|
|
4
58
|
* The spec-independent subset of a client's `ClientConfig` a publisher may bake in
|
|
5
59
|
* (everything except the spec-derived `auth`).
|
|
@@ -24,4 +78,10 @@ export type ClientSetup = {
|
|
|
24
78
|
* @experimental The setup API may change between minor versions until stabilized.
|
|
25
79
|
*/
|
|
26
80
|
export declare function defineClientSetup(setup: ClientSetup): ClientSetup;
|
|
81
|
+
/** One declared response header the runtime coerces into the envelope `headers` object. */
|
|
82
|
+
export type ResponseHeaderSpec = {
|
|
83
|
+
name: string;
|
|
84
|
+
key: string;
|
|
85
|
+
type: 'string' | 'number' | 'boolean';
|
|
86
|
+
};
|
|
27
87
|
//# sourceMappingURL=runtime-contract.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-contract.d.ts","sourceRoot":"","sources":["../src/runtime-contract.ts"],"names":[],"mappings":"AAKA,OAAO,
|
|
1
|
+
{"version":3,"file":"runtime-contract.d.ts","sourceRoot":"","sources":["../src/runtime-contract.ts"],"names":[],"mappings":"AAKA,qFAAqF;AACrF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,aAAa,CAAC;AAEpD;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,CAC1B,EAAE,SAAS,MAAM,GAAG,MAAM,EAC1B,IAAI,SAAS,MAAM,GAAG,MAAM,EAC5B,GAAG,SAAS,MAAM,GAAG,MAAM,IACzB;IAAE,EAAE,EAAE,EAAE,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,GAAG,EAAE,CAAA;CAAE,CAAC;AAExC,yEAAyE;AACzE,MAAM,MAAM,cAAc,CAAC,EAAE,SAAS,gBAAgB,GAAG,gBAAgB,IAAI;IAC3E,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,EAAE,CAAC;CACf,CAAC;AAEF,iGAAiG;AACjG,MAAM,MAAM,YAAY,CAAC,EAAE,SAAS,gBAAgB,GAAG,gBAAgB,IAAI;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;IAC5B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,6FAA6F;AAC7F,MAAM,MAAM,WAAW,CAAC,EAAE,SAAS,gBAAgB,GAAG,gBAAgB,IAAI;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACjE,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,GAAG;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,sDAAsD;AACtD,MAAM,MAAM,UAAU,CAAC,EAAE,SAAS,gBAAgB,GAAG,gBAAgB,IAAI;IACvE,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,UAAU,CAAC,EAAE,CACX,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,cAAc,CAAC,EAAE,CAAC,KACpB,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAChD,kDAAkD;IAElD,OAAO,CAAC,EAAE,CACR,KAAK,EAAE,YAAY,EACnB,GAAG,EAAE,cAAc,CAAC,EAAE,CAAC,KACpB,UAAU,CAAC,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;CACnD,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EACJ,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACtB,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACrE,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,UAAU,CAAC,EAAE,CACX,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,cAAc,KAChB,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,cAAc,KAAK,KAAK,CAAC;IACvD,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAAC,UAAU,CAAC,EAAE,UAAU,EAAE,CAAA;CAAE,CAAC;AAEpF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAEjE;AAED,2FAA2F;AAC3F,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;CACvC,CAAC"}
|
package/lib/runtime-contract.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// The public, spec-independent runtime contract a publisher's `--setup` file imports.
|
|
2
|
-
// These are
|
|
3
|
-
//
|
|
4
|
-
// drift from the generated output.
|
|
2
|
+
// These types are DEFINED here, at the package level, and the TypeScript runtime
|
|
3
|
+
// re-exports them (ADR-0022) — the embed splices the definitions into the generated
|
|
4
|
+
// client's types module, so the contract cannot drift from the generated output.
|
|
5
5
|
/**
|
|
6
6
|
* Identity helper for authoring a `--setup` module: gives full type inference and a stable
|
|
7
7
|
* call the baker recognises. `export default defineClientSetup({ config, middleware })`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-contract.js","sourceRoot":"","sources":["../src/runtime-contract.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,iFAAiF;AACjF,
|
|
1
|
+
{"version":3,"file":"runtime-contract.js","sourceRoot":"","sources":["../src/runtime-contract.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,iFAAiF;AACjF,oFAAoF;AACpF,iFAAiF;AA6FjF;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAkB;IAClD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const GO_RUNTIME_SOURCE = "// Package client \u2014 the embedded runtime for generated Go SDKs. Hand-authored\n// once and stitched into every generated client (see\n// scripts/generate-runtime-sources.mjs), semantically in lockstep with the\n// TypeScript runtime: auth OR-alternatives, a retry loop with Retry-After and\n// full-jitter backoff, per-attempt timeouts, idempotency keys, and middleware\n// hooks. Standard library only \u2014 a generated Go SDK has zero dependencies.\npackage client\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/rand\"\n\t\"mime/multipart\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// APIError is returned for a non-2xx response, carrying the decoded error body.\ntype APIError struct {\n\tURL string\n\tStatus int\n\tStatusText string\n\tBody any\n}\n\nfunc (e *APIError) Error() string {\n\treturn fmt.Sprintf(\"request failed with status %d\", e.Status)\n}\n\n// TimeoutError is returned when a request attempt exceeds the configured\n// timeout \u2014 carrying the context a log line needs.\ntype TimeoutError struct {\n\tOperationID string\n\tTimeout time.Duration\n\tAttempt int\n}\n\nfunc (e *TimeoutError) Error() string {\n\treturn fmt.Sprintf(\"request %q timed out after %s (attempt %d)\", e.OperationID, e.Timeout, e.Attempt)\n}\n\n// SecuritySpec mirrors the descriptor table's security entries.\ntype SecuritySpec struct {\n\tScheme string\n\tKind string // \"bearer\" | \"basic\" | \"apiKey\"\n\tName string // header/query/cookie name for apiKey\n\tIn string // \"header\" | \"query\" | \"cookie\"\n}\n\n// Auth holds the client credentials; zero value = anonymous.\ntype Auth struct {\n\tBearer func() string\n\tBasic *BasicAuth\n\tAPIKey map[string]func() string\n}\n\ntype BasicAuth struct {\n\tUsername string\n\tPassword string\n}\n\n// RetryConfig mirrors the TypeScript runtime's retry policy knobs.\ntype RetryConfig struct {\n\tRetries int\n\tRetryDelay time.Duration // base; default 1s\n\tRetryStrategy string // \"\" (exponential) | \"fixed\"\n\tNoJitter bool\n\t// RetryOn fully replaces the default predicate when set.\n\tRetryOn func(attempt int, resp *http.Response, err error) bool\n}\n\n// Middleware hooks run around every request (OnRequest before serialization order\n// is N/A in Go \u2014 bodies are values; OnResponse runs in reverse registration order).\ntype Middleware struct {\n\tOnRequest func(req *http.Request)\n\tOnResponse func(resp *http.Response)\n}\n\n// Date is an RFC 3339 full-date \u2014 a calendar date with no time component. Fields\n// typed `date` under `dateType: Date` use it because encoding/json speaks only\n// RFC 3339 date-time for time.Time, which a bare \"2006-01-02\" fails to satisfy.\ntype Date struct {\n\ttime.Time\n}\n\nconst dateLayout = \"2006-01-02\"\n\n// UnmarshalJSON parses a \"2006-01-02\" string; an empty string leaves the zero value.\nfunc (d *Date) UnmarshalJSON(data []byte) error {\n\tvar raw string\n\tif err := json.Unmarshal(data, &raw); err != nil {\n\t\treturn err\n\t}\n\tif raw == \"\" {\n\t\treturn nil\n\t}\n\tparsed, err := time.Parse(dateLayout, raw)\n\tif err != nil {\n\t\treturn err\n\t}\n\td.Time = parsed\n\treturn nil\n}\n\n// MarshalJSON writes the date back without a time component.\nfunc (d Date) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(d.Format(dateLayout))\n}\n\n// Config is the per-client configuration shared by every operation method.\ntype Config struct {\n\tServerURL string\n\tHTTPClient *http.Client\n\tHeaders map[string]string\n\tTimeout time.Duration\n\tRetry RetryConfig\n\tMiddleware []Middleware\n\tIdempotencyKey func() string\n\tAuth Auth\n}\n\nfunc resolveToken(provider func() string) string {\n\tif provider == nil {\n\t\treturn \"\"\n\t}\n\treturn provider()\n}\n\nfunc schemeConfigured(spec SecuritySpec, auth Auth) bool {\n\tswitch spec.Kind {\n\tcase \"apiKey\":\n\t\t_, ok := auth.APIKey[spec.Scheme]\n\t\treturn ok\n\tcase \"bearer\":\n\t\treturn auth.Bearer != nil\n\tdefault:\n\t\treturn auth.Basic != nil\n\t}\n}\n\n// resolveAuth applies the first fully-configured OR-alternative; when none is,\n// the first alternative's configured schemes are still sent (the server rejects\n// the request \u2014 same behavior as the TypeScript runtime).\nfunc resolveAuth(security [][]SecuritySpec, auth Auth) (map[string]string, url.Values) {\n\theaders := map[string]string{}\n\tquery := url.Values{}\n\tif len(security) == 0 {\n\t\treturn headers, query\n\t}\n\talternative := security[0]\n\tfor _, candidate := range security {\n\t\tall := true\n\t\tfor _, spec := range candidate {\n\t\t\tif !schemeConfigured(spec, auth) {\n\t\t\t\tall = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif all {\n\t\t\talternative = candidate\n\t\t\tbreak\n\t\t}\n\t}\n\tvar cookies []string\n\tfor _, spec := range alternative {\n\t\tswitch spec.Kind {\n\t\tcase \"apiKey\":\n\t\t\tprovider, ok := auth.APIKey[spec.Scheme]\n\t\t\tif !ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvalue := resolveToken(provider)\n\t\t\tswitch spec.In {\n\t\t\tcase \"query\":\n\t\t\t\tquery.Set(spec.Name, value)\n\t\t\tcase \"cookie\":\n\t\t\t\tcookies = append(cookies, spec.Name+\"=\"+url.QueryEscape(value))\n\t\t\tdefault:\n\t\t\t\theaders[spec.Name] = value\n\t\t\t}\n\t\tcase \"bearer\":\n\t\t\tif auth.Bearer != nil {\n\t\t\t\theaders[\"Authorization\"] = \"Bearer \" + resolveToken(auth.Bearer)\n\t\t\t}\n\t\tdefault:\n\t\t\tif auth.Basic != nil {\n\t\t\t\ttoken := base64.StdEncoding.EncodeToString([]byte(auth.Basic.Username + \":\" + auth.Basic.Password))\n\t\t\t\theaders[\"Authorization\"] = \"Basic \" + token\n\t\t\t}\n\t\t}\n\t}\n\tif len(cookies) > 0 {\n\t\theaders[\"Cookie\"] = strings.Join(cookies, \"; \")\n\t}\n\treturn headers, query\n}\n\n// buildURL substitutes {param} path placeholders with percent-encoded values.\nfunc buildURL(serverURL, path string, pathParams map[string]string) string {\n\tfilled := path\n\tfor name, value := range pathParams {\n\t\tfilled = strings.ReplaceAll(filled, \"{\"+name+\"}\", url.PathEscape(value))\n\t}\n\treturn strings.TrimRight(serverURL, \"/\") + filled\n}\n\nvar transientStatus = map[int]bool{408: true, 429: true, 500: true, 502: true, 503: true, 504: true}\n\nfunc defaultRetryOn(method string, headers map[string]string, resp *http.Response, err error) bool {\n\tsafe := false\n\tswitch strings.ToUpper(method) {\n\tcase \"GET\", \"HEAD\", \"PUT\", \"DELETE\", \"OPTIONS\":\n\t\tsafe = true\n\t}\n\tif _, ok := headers[\"Idempotency-Key\"]; ok {\n\t\tsafe = true\n\t}\n\tif !safe {\n\t\treturn false\n\t}\n\tif err != nil {\n\t\treturn true\n\t}\n\treturn resp != nil && transientStatus[resp.StatusCode]\n}\n\nfunc retryDelay(retry RetryConfig, attempt int, retryAfter string) time.Duration {\n\tif retryAfter != \"\" {\n\t\tif seconds, err := strconv.ParseFloat(retryAfter, 64); err == nil {\n\t\t\treturn time.Duration(seconds * float64(time.Second))\n\t\t}\n\t}\n\tbase := retry.RetryDelay\n\tif base == 0 {\n\t\tbase = time.Second\n\t}\n\traw := base\n\tif retry.RetryStrategy != \"fixed\" {\n\t\traw = base * time.Duration(1<<(attempt-1))\n\t}\n\tif retry.NoJitter {\n\t\treturn raw\n\t}\n\treturn time.Duration(rand.Int63n(int64(raw) + 1))\n}\n\ntype requestSpec struct {\n\tOperationID string\n\tMethod string\n\tURL string\n\tHeaders map[string]string\n\tQuery url.Values\n\tBody io.Reader\n\tContentType string\n\tTimeout time.Duration\n\tRetry *RetryConfig\n\tIdempotencyKey string\n\t// bodyBytes is retained so retries can replay the body.\n\tbodyBytes []byte\n}\n\n// send is the request core: header merge, idempotency keys, the retry loop\n// (fresh timeout budget per attempt), and the middleware onion.\nfunc send(ctx context.Context, config *Config, spec requestSpec) (*http.Response, error) {\n\tretry := config.Retry\n\tif spec.Retry != nil {\n\t\tretry = *spec.Retry\n\t}\n\ttimeout := config.Timeout\n\tif spec.Timeout != 0 {\n\t\ttimeout = spec.Timeout\n\t}\n\theaders := map[string]string{}\n\tfor key, value := range config.Headers {\n\t\theaders[key] = value\n\t}\n\tfor key, value := range spec.Headers {\n\t\theaders[key] = value\n\t}\n\tmethod := strings.ToUpper(spec.Method)\n\tif (method == \"POST\" || method == \"PATCH\") && headers[\"Idempotency-Key\"] == \"\" {\n\t\tif spec.IdempotencyKey != \"\" {\n\t\t\theaders[\"Idempotency-Key\"] = spec.IdempotencyKey\n\t\t} else if config.IdempotencyKey != nil {\n\t\t\theaders[\"Idempotency-Key\"] = config.IdempotencyKey()\n\t\t}\n\t}\n\thttpClient := config.HTTPClient\n\tif httpClient == nil {\n\t\thttpClient = http.DefaultClient\n\t}\n\tif spec.Body != nil {\n\t\tpayload, err := io.ReadAll(spec.Body)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tspec.bodyBytes = payload\n\t}\n\tfullURL := spec.URL\n\tif len(spec.Query) > 0 {\n\t\tseparator := \"?\"\n\t\tif strings.Contains(fullURL, \"?\") {\n\t\t\tseparator = \"&\"\n\t\t}\n\t\tfullURL += separator + spec.Query.Encode()\n\t}\n\tmaxAttempts := 1 + retry.Retries\n\tfor attempt := 1; ; attempt++ {\n\t\tattemptCtx := ctx\n\t\tvar cancel context.CancelFunc\n\t\tif timeout > 0 {\n\t\t\tattemptCtx, cancel = context.WithTimeout(ctx, timeout)\n\t\t}\n\t\tvar bodyReader io.Reader\n\t\tif spec.bodyBytes != nil {\n\t\t\tbodyReader = bytes.NewReader(spec.bodyBytes)\n\t\t}\n\t\treq, err := http.NewRequestWithContext(attemptCtx, method, fullURL, bodyReader)\n\t\tif err != nil {\n\t\t\tif cancel != nil {\n\t\t\t\tcancel()\n\t\t\t}\n\t\t\treturn nil, err\n\t\t}\n\t\tfor key, value := range headers {\n\t\t\treq.Header.Set(key, value)\n\t\t}\n\t\tif spec.ContentType != \"\" && spec.bodyBytes != nil {\n\t\t\treq.Header.Set(\"Content-Type\", spec.ContentType)\n\t\t}\n\t\tfor _, mw := range config.Middleware {\n\t\t\tif mw.OnRequest != nil {\n\t\t\t\tmw.OnRequest(req)\n\t\t\t}\n\t\t}\n\t\tresp, err := httpClient.Do(req)\n\t\tshouldRetry := retry.RetryOn\n\t\tretryable := false\n\t\tif shouldRetry != nil {\n\t\t\tretryable = shouldRetry(attempt, resp, err)\n\t\t} else {\n\t\t\tretryable = defaultRetryOn(method, headers, resp, err)\n\t\t}\n\t\tif err != nil {\n\t\t\tif cancel != nil {\n\t\t\t\tcancel()\n\t\t\t}\n\t\t\ttimedOut := errors.Is(err, context.DeadlineExceeded) && ctx.Err() == nil\n\t\t\tif attempt < maxAttempts && retryable {\n\t\t\t\ttime.Sleep(retryDelay(retry, attempt, \"\"))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif timedOut {\n\t\t\t\treturn nil, &TimeoutError{OperationID: spec.OperationID, Timeout: timeout, Attempt: attempt}\n\t\t\t}\n\t\t\treturn nil, err\n\t\t}\n\t\tfor i := len(config.Middleware) - 1; i >= 0; i-- {\n\t\t\tif config.Middleware[i].OnResponse != nil {\n\t\t\t\tconfig.Middleware[i].OnResponse(resp)\n\t\t\t}\n\t\t}\n\t\tif resp.StatusCode >= 400 && attempt < maxAttempts && retryable {\n\t\t\tafter := resp.Header.Get(\"Retry-After\")\n\t\t\tio.Copy(io.Discard, resp.Body)\n\t\t\tresp.Body.Close()\n\t\t\tif cancel != nil {\n\t\t\t\tcancel()\n\t\t\t}\n\t\t\ttime.Sleep(retryDelay(retry, attempt, after))\n\t\t\tcontinue\n\t\t}\n\t\t// The response body outlives this call; tie the attempt context's lifetime to it.\n\t\tif cancel != nil {\n\t\t\tresp.Body = &cancelOnClose{ReadCloser: resp.Body, cancel: cancel}\n\t\t}\n\t\treturn resp, nil\n\t}\n}\n\ntype cancelOnClose struct {\n\tio.ReadCloser\n\tcancel context.CancelFunc\n}\n\nfunc (c *cancelOnClose) Close() error {\n\tc.cancel()\n\treturn c.ReadCloser.Close()\n}\n\n// decodeJSON decodes a response body into target; a nil target drains and closes.\nfunc decodeJSON(resp *http.Response, target any) error {\n\tdefer resp.Body.Close()\n\tif target == nil {\n\t\t_, err := io.Copy(io.Discard, resp.Body)\n\t\treturn err\n\t}\n\treturn json.NewDecoder(resp.Body).Decode(target)\n}\n\n// headerString returns the named response header, or nil when absent.\nfunc headerString(header http.Header, name string) *string {\n\tvalue := header.Get(name)\n\tif value == \"\" {\n\t\treturn nil\n\t}\n\treturn &value\n}\n\n// headerInt64 parses the named header as an integer; nil when absent or unparsable.\nfunc headerInt64(header http.Header, name string) *int64 {\n\traw := strings.TrimSpace(header.Get(name))\n\tif raw == \"\" {\n\t\treturn nil\n\t}\n\tvalue, err := strconv.ParseInt(raw, 10, 64)\n\tif err != nil {\n\t\treturn nil\n\t}\n\treturn &value\n}\n\n// headerFloat64 parses the named header as a number; nil when absent or unparsable.\nfunc headerFloat64(header http.Header, name string) *float64 {\n\traw := strings.TrimSpace(header.Get(name))\n\tif raw == \"\" {\n\t\treturn nil\n\t}\n\tvalue, err := strconv.ParseFloat(raw, 64)\n\tif err != nil {\n\t\treturn nil\n\t}\n\treturn &value\n}\n\n// headerBool parses a `true`/`false` header; nil when absent or anything else.\nfunc headerBool(header http.Header, name string) *bool {\n\traw := strings.ToLower(strings.TrimSpace(header.Get(name)))\n\tif raw != \"true\" && raw != \"false\" {\n\t\treturn nil\n\t}\n\tvalue := raw == \"true\"\n\treturn &value\n}\n\n// apiErrorFrom builds the structured error for a non-2xx response.\nfunc apiErrorFrom(resp *http.Response, requestURL string) error {\n\tdefer resp.Body.Close()\n\tvar body any\n\tdata, _ := io.ReadAll(resp.Body)\n\tif len(data) > 0 {\n\t\tif err := json.Unmarshal(data, &body); err != nil {\n\t\t\tbody = string(data)\n\t\t}\n\t}\n\treturn &APIError{URL: requestURL, Status: resp.StatusCode, StatusText: resp.Status, Body: body}\n}\n\n// \u2500\u2500\u2500 Pagination \u2500\u2500\u2500\n\n// PaginationSpec mirrors the descriptor table's pagination entries.\ntype PaginationSpec struct {\n\tStyle string\n\tParam string\n\tNextCursor string\n\tHasMore string\n\tLimitParam string\n\tItems string\n}\n\n// resolvePointer walks an RFC 6901 JSON pointer over decoded JSON; nil on any miss.\nfunc resolvePointer(data any, pointer string) any {\n\tif pointer == \"\" {\n\t\treturn data\n\t}\n\tif !strings.HasPrefix(pointer, \"/\") {\n\t\treturn nil\n\t}\n\tcurrent := data\n\tfor _, token := range strings.Split(pointer[1:], \"/\") {\n\t\tkey := strings.ReplaceAll(strings.ReplaceAll(token, \"~1\", \"/\"), \"~0\", \"~\")\n\t\tswitch typed := current.(type) {\n\t\tcase map[string]any:\n\t\t\tcurrent = typed[key]\n\t\tcase []any:\n\t\t\tindex, err := strconv.Atoi(key)\n\t\t\tif err != nil || index < 0 || index >= len(typed) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tcurrent = typed[index]\n\t\tdefault:\n\t\t\treturn nil\n\t\t}\n\t\tif current == nil {\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn current\n}\n\n// reencode converts decoded JSON (maps/slices) into a typed value via a JSON round-trip.\nfunc reencode(raw any, target any) error {\n\tdata, err := json.Marshal(raw)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn json.Unmarshal(data, target)\n}\n\ntype pageCall func(params url.Values) (any, *http.Response, error)\n\n// iterPages yields raw page JSON per the pagination spec \u2014 the same stop\n// conditions and infinite-loop guards as the TypeScript runtime. The returned\n// function is a range-over-func iterator (Go 1.23+) and plainly callable before that.\nfunc iterPages(call pageCall, spec PaginationSpec, base url.Values) func(yield func(any, error) bool) {\n\treturn func(yield func(any, error) bool) {\n\t\tswitch spec.Style {\n\t\tcase \"cursor\":\n\t\t\tvar cursor any\n\t\t\tif values, ok := base[spec.Param]; ok && len(values) > 0 {\n\t\t\t\tcursor = values[0]\n\t\t\t}\n\t\t\tfor {\n\t\t\t\tparams := cloneValues(base)\n\t\t\t\tif cursor != nil {\n\t\t\t\t\tparams.Set(spec.Param, fmt.Sprint(cursor))\n\t\t\t\t}\n\t\t\t\tpage, _, err := call(params)\n\t\t\t\tif err != nil {\n\t\t\t\t\tyield(nil, err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif !yield(page, nil) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif spec.HasMore != \"\" {\n\t\t\t\t\tif more, ok := resolvePointer(page, spec.HasMore).(bool); ok && !more {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnext := resolvePointer(page, spec.NextCursor)\n\t\t\t\tif next == nil || next == \"\" {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tswitch next.(type) {\n\t\t\t\tcase string, float64:\n\t\t\t\tdefault:\n\t\t\t\t\tyield(nil, fmt.Errorf(\"pagination cursor at %s is not a string or number\", spec.NextCursor))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif cursor != nil && fmt.Sprint(next) == fmt.Sprint(cursor) {\n\t\t\t\t\tyield(nil, errors.New(\"pagination did not advance: the operation returned the same cursor twice\"))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcursor = next\n\t\t\t}\n\t\tcase \"link\":\n\t\t\tparams := cloneValues(base)\n\t\t\tprevious := \"\"\n\t\t\tfor {\n\t\t\t\tpage, resp, err := call(params)\n\t\t\t\tif err != nil {\n\t\t\t\t\tyield(nil, err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif !yield(page, nil) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ttarget := linkNext(resp.Header.Get(\"Link\"))\n\t\t\t\tif target == \"\" {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tpageURL := \"\"\n\t\t\t\tif resp.Request != nil && resp.Request.URL != nil {\n\t\t\t\t\tpageURL = resp.Request.URL.String()\n\t\t\t\t}\n\t\t\t\tbaseURL, err := url.Parse(pageURL)\n\t\t\t\tif err != nil || pageURL == \"\" {\n\t\t\t\t\tbaseURL, _ = url.Parse(\"http://relative.invalid\")\n\t\t\t\t}\n\t\t\t\ttargetURL, err := baseURL.Parse(target)\n\t\t\t\tif err != nil {\n\t\t\t\t\tyield(nil, err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tnext := targetURL.String()\n\t\t\t\tif next == previous || next == pageURL {\n\t\t\t\t\tyield(nil, errors.New(`pagination did not advance: the Link rel=\"next\" target repeats`))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tprevious = next\n\t\t\t\tparams = cloneValues(base)\n\t\t\t\tfor key, values := range targetURL.Query() {\n\t\t\t\t\tfor _, value := range values {\n\t\t\t\t\t\tparams.Add(key, value)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tdefault: // offset / page\n\t\t\tposition := 0\n\t\t\tif spec.Style == \"page\" {\n\t\t\t\tposition = 1\n\t\t\t}\n\t\t\tif values, ok := base[spec.Param]; ok && len(values) > 0 && values[0] != \"\" {\n\t\t\t\tif parsed, err := strconv.Atoi(values[0]); err == nil {\n\t\t\t\t\tposition = parsed\n\t\t\t\t}\n\t\t\t}\n\t\t\tpreviousItems := \"\"\n\t\t\tfor {\n\t\t\t\tparams := cloneValues(base)\n\t\t\t\tparams.Set(spec.Param, strconv.Itoa(position))\n\t\t\t\tpage, _, err := call(params)\n\t\t\t\tif err != nil {\n\t\t\t\t\tyield(nil, err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\titems, _ := resolvePointer(page, spec.Items).([]any)\n\t\t\t\tserialized := \"\"\n\t\t\t\tif items != nil {\n\t\t\t\t\tserialized = fmt.Sprint(items)\n\t\t\t\t\tif serialized == previousItems {\n\t\t\t\t\t\tyield(nil, errors.New(\"pagination did not advance: the operation returned the same page twice\"))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif !yield(page, nil) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif len(items) == 0 {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tpreviousItems = serialized\n\t\t\t\tif spec.Style == \"page\" {\n\t\t\t\t\tposition++\n\t\t\t\t} else {\n\t\t\t\t\tposition += len(items)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc cloneValues(values url.Values) url.Values {\n\tout := url.Values{}\n\tfor key, entries := range values {\n\t\tfor _, entry := range entries {\n\t\t\tout.Add(key, entry)\n\t\t}\n\t}\n\treturn out\n}\n\nfunc linkNext(header string) string {\n\tif header == \"\" {\n\t\treturn \"\"\n\t}\n\tfor _, entry := range strings.Split(header, \",\") {\n\t\tparts := strings.Split(entry, \";\")\n\t\tif len(parts) < 2 {\n\t\t\tcontinue\n\t\t}\n\t\ttarget := strings.TrimSpace(parts[0])\n\t\tif !strings.HasPrefix(target, \"<\") || !strings.HasSuffix(target, \">\") {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, param := range parts[1:] {\n\t\t\ttrimmed := strings.TrimSpace(param)\n\t\t\tif strings.HasPrefix(trimmed, \"rel=\") {\n\t\t\t\trel := strings.Trim(strings.TrimPrefix(trimmed, \"rel=\"), `\"`)\n\t\t\t\tfor _, kind := range strings.Fields(rel) {\n\t\t\t\t\tif kind == \"next\" {\n\t\t\t\t\t\treturn strings.Trim(target, \"<>\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// \u2500\u2500\u2500 Server-Sent Events \u2500\u2500\u2500\n\n// ServerSentEvent is one decoded event; Data is the raw text (or parsed JSON\n// for operations that declare a JSON event stream).\ntype ServerSentEvent struct {\n\tEvent string\n\tData any\n\tID string\n\tRetry int\n}\n\nfunc parseSSEFrame(raw string, jsonData bool) (ServerSentEvent, bool, error) {\n\tevent := ServerSentEvent{Retry: -1}\n\tsawField := false\n\tvar dataLines []string\n\tnormalized := strings.ReplaceAll(strings.ReplaceAll(raw, \"\\r\\n\", \"\\n\"), \"\\r\", \"\\n\")\n\tfor _, line := range strings.Split(normalized, \"\\n\") {\n\t\tif line == \"\" || strings.HasPrefix(line, \":\") {\n\t\t\tcontinue\n\t\t}\n\t\tfield, value, _ := strings.Cut(line, \":\")\n\t\tvalue = strings.TrimPrefix(value, \" \")\n\t\tsawField = true\n\t\tswitch field {\n\t\tcase \"event\":\n\t\t\tevent.Event = value\n\t\tcase \"data\":\n\t\t\tdataLines = append(dataLines, value)\n\t\tcase \"id\":\n\t\t\tevent.ID = value\n\t\tcase \"retry\":\n\t\t\tif parsed, err := strconv.Atoi(value); err == nil && parsed >= 0 && value != \"\" {\n\t\t\t\tevent.Retry = parsed\n\t\t\t}\n\t\t}\n\t}\n\tif !sawField {\n\t\treturn event, false, nil\n\t}\n\ttext := strings.Join(dataLines, \"\\n\")\n\tevent.Data = text\n\tif jsonData && text != \"\" {\n\t\tvar parsed any\n\t\tif err := json.Unmarshal([]byte(text), &parsed); err != nil {\n\t\t\treturn event, false, err\n\t\t}\n\t\tevent.Data = parsed\n\t}\n\treturn event, true, nil\n}\n\n// iterSSE streams events, reconnecting on dropped connections with Last-Event-ID\n// (a fresh open call = fresh auth); a 4xx/5xx or a bad JSON payload is definitive.\nfunc iterSSE(open func(extraHeaders map[string]string) (*http.Response, error), jsonData bool) func(yield func(ServerSentEvent, error) bool) {\n\treturn func(yield func(ServerSentEvent, error) bool) {\n\t\tlastEventID := \"\"\n\t\tserverRetry := -1\n\t\tfailures := 0\n\t\tfor {\n\t\t\theaders := map[string]string{\"Accept\": \"text/event-stream\"}\n\t\t\tif lastEventID != \"\" {\n\t\t\t\theaders[\"Last-Event-ID\"] = lastEventID\n\t\t\t}\n\t\t\tresp, err := open(headers)\n\t\t\tif err == nil && resp.StatusCode >= 400 {\n\t\t\t\tyield(ServerSentEvent{}, apiErrorFrom(resp, \"\"))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err == nil {\n\t\t\t\tfailures = 0\n\t\t\t\tbuffer := \"\"\n\t\t\t\tchunk := make([]byte, 4096)\n\t\t\t\tclean := false\n\t\t\t\tfor {\n\t\t\t\t\tn, readErr := resp.Body.Read(chunk)\n\t\t\t\t\tbuffer += string(chunk[:n])\n\t\t\t\t\tfor {\n\t\t\t\t\t\tframe, rest, found := strings.Cut(buffer, \"\\n\\n\")\n\t\t\t\t\t\tif !found {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbuffer = rest\n\t\t\t\t\t\tevent, ok, parseErr := parseSSEFrame(frame, jsonData)\n\t\t\t\t\t\tif parseErr != nil {\n\t\t\t\t\t\t\tresp.Body.Close()\n\t\t\t\t\t\t\tyield(ServerSentEvent{}, parseErr)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ok {\n\t\t\t\t\t\t\tif event.ID != \"\" {\n\t\t\t\t\t\t\t\tlastEventID = event.ID\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif event.Retry >= 0 {\n\t\t\t\t\t\t\t\tserverRetry = event.Retry\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif !yield(event, nil) {\n\t\t\t\t\t\t\t\tresp.Body.Close()\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif readErr == io.EOF {\n\t\t\t\t\t\tclean = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tif readErr != nil {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresp.Body.Close()\n\t\t\t\tif clean {\n\t\t\t\t\tif strings.TrimSpace(buffer) != \"\" {\n\t\t\t\t\t\tif event, ok, parseErr := parseSSEFrame(buffer, jsonData); parseErr == nil && ok {\n\t\t\t\t\t\t\tyield(event, nil)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tfailures++\n\t\t\tbase := time.Second\n\t\t\tif serverRetry >= 0 {\n\t\t\t\tbase = time.Duration(serverRetry) * time.Millisecond\n\t\t\t}\n\t\t\tdelay := base * time.Duration(1<<(failures-1))\n\t\t\tif delay > 30*time.Second {\n\t\t\t\tdelay = 30 * time.Second\n\t\t\t}\n\t\t\ttime.Sleep(time.Duration(rand.Int63n(int64(delay) + 1)))\n\t\t}\n\t}\n}\n\n// \u2500\u2500\u2500 Multipart \u2500\u2500\u2500\n\n// toMultipart splits a typed body into a multipart/form-data payload: []byte\n// values upload as file parts, everything else as form fields (nested values\n// JSON-encoded) \u2014 mirroring the TypeScript runtime's FormData serialization.\nfunc toMultipart(body any) (string, io.Reader, error) {\n\tvar wire map[string]any\n\tif err := reencode(body, &wire); err != nil {\n\t\treturn \"\", nil, err\n\t}\n\tbuffer := &bytes.Buffer{}\n\twriter := multipart.NewWriter(buffer)\n\tfor key, value := range wire {\n\t\tswitch typed := value.(type) {\n\t\tcase string:\n\t\t\tif err := writer.WriteField(key, typed); err != nil {\n\t\t\t\treturn \"\", nil, err\n\t\t\t}\n\t\tcase float64, bool:\n\t\t\tif err := writer.WriteField(key, fmt.Sprint(typed)); err != nil {\n\t\t\t\treturn \"\", nil, err\n\t\t\t}\n\t\tdefault:\n\t\t\tencoded, err := json.Marshal(typed)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", nil, err\n\t\t\t}\n\t\t\tif err := writer.WriteField(key, string(encoded)); err != nil {\n\t\t\t\treturn \"\", nil, err\n\t\t\t}\n\t\t}\n\t}\n\tif err := writer.Close(); err != nil {\n\t\treturn \"\", nil, err\n\t}\n\treturn writer.FormDataContentType(), buffer, nil\n}\n";
|
|
2
|
+
//# sourceMappingURL=go.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go.d.ts","sourceRoot":"","sources":["../../src/runtime-sources/go.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,iBAAiB,uzxBAC63wB,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// GENERATED by scripts/generate-runtime-sources.mjs — do not edit. Regenerated on install (`prepare`); manually: `npm run prepare -w @redocly/client-generator`.
|
|
2
|
+
export const GO_RUNTIME_SOURCE = '// Package client — the embedded runtime for generated Go SDKs. Hand-authored\n// once and stitched into every generated client (see\n// scripts/generate-runtime-sources.mjs), semantically in lockstep with the\n// TypeScript runtime: auth OR-alternatives, a retry loop with Retry-After and\n// full-jitter backoff, per-attempt timeouts, idempotency keys, and middleware\n// hooks. Standard library only — a generated Go SDK has zero dependencies.\npackage client\n\nimport (\n\t"bytes"\n\t"context"\n\t"encoding/base64"\n\t"encoding/json"\n\t"errors"\n\t"fmt"\n\t"io"\n\t"math/rand"\n\t"mime/multipart"\n\t"net/http"\n\t"net/url"\n\t"strconv"\n\t"strings"\n\t"time"\n)\n\n// APIError is returned for a non-2xx response, carrying the decoded error body.\ntype APIError struct {\n\tURL string\n\tStatus int\n\tStatusText string\n\tBody any\n}\n\nfunc (e *APIError) Error() string {\n\treturn fmt.Sprintf("request failed with status %d", e.Status)\n}\n\n// TimeoutError is returned when a request attempt exceeds the configured\n// timeout — carrying the context a log line needs.\ntype TimeoutError struct {\n\tOperationID string\n\tTimeout time.Duration\n\tAttempt int\n}\n\nfunc (e *TimeoutError) Error() string {\n\treturn fmt.Sprintf("request %q timed out after %s (attempt %d)", e.OperationID, e.Timeout, e.Attempt)\n}\n\n// SecuritySpec mirrors the descriptor table\'s security entries.\ntype SecuritySpec struct {\n\tScheme string\n\tKind string // "bearer" | "basic" | "apiKey"\n\tName string // header/query/cookie name for apiKey\n\tIn string // "header" | "query" | "cookie"\n}\n\n// Auth holds the client credentials; zero value = anonymous.\ntype Auth struct {\n\tBearer func() string\n\tBasic *BasicAuth\n\tAPIKey map[string]func() string\n}\n\ntype BasicAuth struct {\n\tUsername string\n\tPassword string\n}\n\n// RetryConfig mirrors the TypeScript runtime\'s retry policy knobs.\ntype RetryConfig struct {\n\tRetries int\n\tRetryDelay time.Duration // base; default 1s\n\tRetryStrategy string // "" (exponential) | "fixed"\n\tNoJitter bool\n\t// RetryOn fully replaces the default predicate when set.\n\tRetryOn func(attempt int, resp *http.Response, err error) bool\n}\n\n// Middleware hooks run around every request (OnRequest before serialization order\n// is N/A in Go — bodies are values; OnResponse runs in reverse registration order).\ntype Middleware struct {\n\tOnRequest func(req *http.Request)\n\tOnResponse func(resp *http.Response)\n}\n\n// Date is an RFC 3339 full-date — a calendar date with no time component. Fields\n// typed `date` under `dateType: Date` use it because encoding/json speaks only\n// RFC 3339 date-time for time.Time, which a bare "2006-01-02" fails to satisfy.\ntype Date struct {\n\ttime.Time\n}\n\nconst dateLayout = "2006-01-02"\n\n// UnmarshalJSON parses a "2006-01-02" string; an empty string leaves the zero value.\nfunc (d *Date) UnmarshalJSON(data []byte) error {\n\tvar raw string\n\tif err := json.Unmarshal(data, &raw); err != nil {\n\t\treturn err\n\t}\n\tif raw == "" {\n\t\treturn nil\n\t}\n\tparsed, err := time.Parse(dateLayout, raw)\n\tif err != nil {\n\t\treturn err\n\t}\n\td.Time = parsed\n\treturn nil\n}\n\n// MarshalJSON writes the date back without a time component.\nfunc (d Date) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(d.Format(dateLayout))\n}\n\n// Config is the per-client configuration shared by every operation method.\ntype Config struct {\n\tServerURL string\n\tHTTPClient *http.Client\n\tHeaders map[string]string\n\tTimeout time.Duration\n\tRetry RetryConfig\n\tMiddleware []Middleware\n\tIdempotencyKey func() string\n\tAuth Auth\n}\n\nfunc resolveToken(provider func() string) string {\n\tif provider == nil {\n\t\treturn ""\n\t}\n\treturn provider()\n}\n\nfunc schemeConfigured(spec SecuritySpec, auth Auth) bool {\n\tswitch spec.Kind {\n\tcase "apiKey":\n\t\t_, ok := auth.APIKey[spec.Scheme]\n\t\treturn ok\n\tcase "bearer":\n\t\treturn auth.Bearer != nil\n\tdefault:\n\t\treturn auth.Basic != nil\n\t}\n}\n\n// resolveAuth applies the first fully-configured OR-alternative; when none is,\n// the first alternative\'s configured schemes are still sent (the server rejects\n// the request — same behavior as the TypeScript runtime).\nfunc resolveAuth(security [][]SecuritySpec, auth Auth) (map[string]string, url.Values) {\n\theaders := map[string]string{}\n\tquery := url.Values{}\n\tif len(security) == 0 {\n\t\treturn headers, query\n\t}\n\talternative := security[0]\n\tfor _, candidate := range security {\n\t\tall := true\n\t\tfor _, spec := range candidate {\n\t\t\tif !schemeConfigured(spec, auth) {\n\t\t\t\tall = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif all {\n\t\t\talternative = candidate\n\t\t\tbreak\n\t\t}\n\t}\n\tvar cookies []string\n\tfor _, spec := range alternative {\n\t\tswitch spec.Kind {\n\t\tcase "apiKey":\n\t\t\tprovider, ok := auth.APIKey[spec.Scheme]\n\t\t\tif !ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvalue := resolveToken(provider)\n\t\t\tswitch spec.In {\n\t\t\tcase "query":\n\t\t\t\tquery.Set(spec.Name, value)\n\t\t\tcase "cookie":\n\t\t\t\tcookies = append(cookies, spec.Name+"="+url.QueryEscape(value))\n\t\t\tdefault:\n\t\t\t\theaders[spec.Name] = value\n\t\t\t}\n\t\tcase "bearer":\n\t\t\tif auth.Bearer != nil {\n\t\t\t\theaders["Authorization"] = "Bearer " + resolveToken(auth.Bearer)\n\t\t\t}\n\t\tdefault:\n\t\t\tif auth.Basic != nil {\n\t\t\t\ttoken := base64.StdEncoding.EncodeToString([]byte(auth.Basic.Username + ":" + auth.Basic.Password))\n\t\t\t\theaders["Authorization"] = "Basic " + token\n\t\t\t}\n\t\t}\n\t}\n\tif len(cookies) > 0 {\n\t\theaders["Cookie"] = strings.Join(cookies, "; ")\n\t}\n\treturn headers, query\n}\n\n// buildURL substitutes {param} path placeholders with percent-encoded values.\nfunc buildURL(serverURL, path string, pathParams map[string]string) string {\n\tfilled := path\n\tfor name, value := range pathParams {\n\t\tfilled = strings.ReplaceAll(filled, "{"+name+"}", url.PathEscape(value))\n\t}\n\treturn strings.TrimRight(serverURL, "/") + filled\n}\n\nvar transientStatus = map[int]bool{408: true, 429: true, 500: true, 502: true, 503: true, 504: true}\n\nfunc defaultRetryOn(method string, headers map[string]string, resp *http.Response, err error) bool {\n\tsafe := false\n\tswitch strings.ToUpper(method) {\n\tcase "GET", "HEAD", "PUT", "DELETE", "OPTIONS":\n\t\tsafe = true\n\t}\n\tif _, ok := headers["Idempotency-Key"]; ok {\n\t\tsafe = true\n\t}\n\tif !safe {\n\t\treturn false\n\t}\n\tif err != nil {\n\t\treturn true\n\t}\n\treturn resp != nil && transientStatus[resp.StatusCode]\n}\n\nfunc retryDelay(retry RetryConfig, attempt int, retryAfter string) time.Duration {\n\tif retryAfter != "" {\n\t\tif seconds, err := strconv.ParseFloat(retryAfter, 64); err == nil {\n\t\t\treturn time.Duration(seconds * float64(time.Second))\n\t\t}\n\t}\n\tbase := retry.RetryDelay\n\tif base == 0 {\n\t\tbase = time.Second\n\t}\n\traw := base\n\tif retry.RetryStrategy != "fixed" {\n\t\traw = base * time.Duration(1<<(attempt-1))\n\t}\n\tif retry.NoJitter {\n\t\treturn raw\n\t}\n\treturn time.Duration(rand.Int63n(int64(raw) + 1))\n}\n\ntype requestSpec struct {\n\tOperationID string\n\tMethod string\n\tURL string\n\tHeaders map[string]string\n\tQuery url.Values\n\tBody io.Reader\n\tContentType string\n\tTimeout time.Duration\n\tRetry *RetryConfig\n\tIdempotencyKey string\n\t// bodyBytes is retained so retries can replay the body.\n\tbodyBytes []byte\n}\n\n// send is the request core: header merge, idempotency keys, the retry loop\n// (fresh timeout budget per attempt), and the middleware onion.\nfunc send(ctx context.Context, config *Config, spec requestSpec) (*http.Response, error) {\n\tretry := config.Retry\n\tif spec.Retry != nil {\n\t\tretry = *spec.Retry\n\t}\n\ttimeout := config.Timeout\n\tif spec.Timeout != 0 {\n\t\ttimeout = spec.Timeout\n\t}\n\theaders := map[string]string{}\n\tfor key, value := range config.Headers {\n\t\theaders[key] = value\n\t}\n\tfor key, value := range spec.Headers {\n\t\theaders[key] = value\n\t}\n\tmethod := strings.ToUpper(spec.Method)\n\tif (method == "POST" || method == "PATCH") && headers["Idempotency-Key"] == "" {\n\t\tif spec.IdempotencyKey != "" {\n\t\t\theaders["Idempotency-Key"] = spec.IdempotencyKey\n\t\t} else if config.IdempotencyKey != nil {\n\t\t\theaders["Idempotency-Key"] = config.IdempotencyKey()\n\t\t}\n\t}\n\thttpClient := config.HTTPClient\n\tif httpClient == nil {\n\t\thttpClient = http.DefaultClient\n\t}\n\tif spec.Body != nil {\n\t\tpayload, err := io.ReadAll(spec.Body)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tspec.bodyBytes = payload\n\t}\n\tfullURL := spec.URL\n\tif len(spec.Query) > 0 {\n\t\tseparator := "?"\n\t\tif strings.Contains(fullURL, "?") {\n\t\t\tseparator = "&"\n\t\t}\n\t\tfullURL += separator + spec.Query.Encode()\n\t}\n\tmaxAttempts := 1 + retry.Retries\n\tfor attempt := 1; ; attempt++ {\n\t\tattemptCtx := ctx\n\t\tvar cancel context.CancelFunc\n\t\tif timeout > 0 {\n\t\t\tattemptCtx, cancel = context.WithTimeout(ctx, timeout)\n\t\t}\n\t\tvar bodyReader io.Reader\n\t\tif spec.bodyBytes != nil {\n\t\t\tbodyReader = bytes.NewReader(spec.bodyBytes)\n\t\t}\n\t\treq, err := http.NewRequestWithContext(attemptCtx, method, fullURL, bodyReader)\n\t\tif err != nil {\n\t\t\tif cancel != nil {\n\t\t\t\tcancel()\n\t\t\t}\n\t\t\treturn nil, err\n\t\t}\n\t\tfor key, value := range headers {\n\t\t\treq.Header.Set(key, value)\n\t\t}\n\t\tif spec.ContentType != "" && spec.bodyBytes != nil {\n\t\t\treq.Header.Set("Content-Type", spec.ContentType)\n\t\t}\n\t\tfor _, mw := range config.Middleware {\n\t\t\tif mw.OnRequest != nil {\n\t\t\t\tmw.OnRequest(req)\n\t\t\t}\n\t\t}\n\t\tresp, err := httpClient.Do(req)\n\t\tshouldRetry := retry.RetryOn\n\t\tretryable := false\n\t\tif shouldRetry != nil {\n\t\t\tretryable = shouldRetry(attempt, resp, err)\n\t\t} else {\n\t\t\tretryable = defaultRetryOn(method, headers, resp, err)\n\t\t}\n\t\tif err != nil {\n\t\t\tif cancel != nil {\n\t\t\t\tcancel()\n\t\t\t}\n\t\t\ttimedOut := errors.Is(err, context.DeadlineExceeded) && ctx.Err() == nil\n\t\t\tif attempt < maxAttempts && retryable {\n\t\t\t\ttime.Sleep(retryDelay(retry, attempt, ""))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif timedOut {\n\t\t\t\treturn nil, &TimeoutError{OperationID: spec.OperationID, Timeout: timeout, Attempt: attempt}\n\t\t\t}\n\t\t\treturn nil, err\n\t\t}\n\t\tfor i := len(config.Middleware) - 1; i >= 0; i-- {\n\t\t\tif config.Middleware[i].OnResponse != nil {\n\t\t\t\tconfig.Middleware[i].OnResponse(resp)\n\t\t\t}\n\t\t}\n\t\tif resp.StatusCode >= 400 && attempt < maxAttempts && retryable {\n\t\t\tafter := resp.Header.Get("Retry-After")\n\t\t\tio.Copy(io.Discard, resp.Body)\n\t\t\tresp.Body.Close()\n\t\t\tif cancel != nil {\n\t\t\t\tcancel()\n\t\t\t}\n\t\t\ttime.Sleep(retryDelay(retry, attempt, after))\n\t\t\tcontinue\n\t\t}\n\t\t// The response body outlives this call; tie the attempt context\'s lifetime to it.\n\t\tif cancel != nil {\n\t\t\tresp.Body = &cancelOnClose{ReadCloser: resp.Body, cancel: cancel}\n\t\t}\n\t\treturn resp, nil\n\t}\n}\n\ntype cancelOnClose struct {\n\tio.ReadCloser\n\tcancel context.CancelFunc\n}\n\nfunc (c *cancelOnClose) Close() error {\n\tc.cancel()\n\treturn c.ReadCloser.Close()\n}\n\n// decodeJSON decodes a response body into target; a nil target drains and closes.\nfunc decodeJSON(resp *http.Response, target any) error {\n\tdefer resp.Body.Close()\n\tif target == nil {\n\t\t_, err := io.Copy(io.Discard, resp.Body)\n\t\treturn err\n\t}\n\treturn json.NewDecoder(resp.Body).Decode(target)\n}\n\n// headerString returns the named response header, or nil when absent.\nfunc headerString(header http.Header, name string) *string {\n\tvalue := header.Get(name)\n\tif value == "" {\n\t\treturn nil\n\t}\n\treturn &value\n}\n\n// headerInt64 parses the named header as an integer; nil when absent or unparsable.\nfunc headerInt64(header http.Header, name string) *int64 {\n\traw := strings.TrimSpace(header.Get(name))\n\tif raw == "" {\n\t\treturn nil\n\t}\n\tvalue, err := strconv.ParseInt(raw, 10, 64)\n\tif err != nil {\n\t\treturn nil\n\t}\n\treturn &value\n}\n\n// headerFloat64 parses the named header as a number; nil when absent or unparsable.\nfunc headerFloat64(header http.Header, name string) *float64 {\n\traw := strings.TrimSpace(header.Get(name))\n\tif raw == "" {\n\t\treturn nil\n\t}\n\tvalue, err := strconv.ParseFloat(raw, 64)\n\tif err != nil {\n\t\treturn nil\n\t}\n\treturn &value\n}\n\n// headerBool parses a `true`/`false` header; nil when absent or anything else.\nfunc headerBool(header http.Header, name string) *bool {\n\traw := strings.ToLower(strings.TrimSpace(header.Get(name)))\n\tif raw != "true" && raw != "false" {\n\t\treturn nil\n\t}\n\tvalue := raw == "true"\n\treturn &value\n}\n\n// apiErrorFrom builds the structured error for a non-2xx response.\nfunc apiErrorFrom(resp *http.Response, requestURL string) error {\n\tdefer resp.Body.Close()\n\tvar body any\n\tdata, _ := io.ReadAll(resp.Body)\n\tif len(data) > 0 {\n\t\tif err := json.Unmarshal(data, &body); err != nil {\n\t\t\tbody = string(data)\n\t\t}\n\t}\n\treturn &APIError{URL: requestURL, Status: resp.StatusCode, StatusText: resp.Status, Body: body}\n}\n\n// ─── Pagination ───\n\n// PaginationSpec mirrors the descriptor table\'s pagination entries.\ntype PaginationSpec struct {\n\tStyle string\n\tParam string\n\tNextCursor string\n\tHasMore string\n\tLimitParam string\n\tItems string\n}\n\n// resolvePointer walks an RFC 6901 JSON pointer over decoded JSON; nil on any miss.\nfunc resolvePointer(data any, pointer string) any {\n\tif pointer == "" {\n\t\treturn data\n\t}\n\tif !strings.HasPrefix(pointer, "/") {\n\t\treturn nil\n\t}\n\tcurrent := data\n\tfor _, token := range strings.Split(pointer[1:], "/") {\n\t\tkey := strings.ReplaceAll(strings.ReplaceAll(token, "~1", "/"), "~0", "~")\n\t\tswitch typed := current.(type) {\n\t\tcase map[string]any:\n\t\t\tcurrent = typed[key]\n\t\tcase []any:\n\t\t\tindex, err := strconv.Atoi(key)\n\t\t\tif err != nil || index < 0 || index >= len(typed) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tcurrent = typed[index]\n\t\tdefault:\n\t\t\treturn nil\n\t\t}\n\t\tif current == nil {\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn current\n}\n\n// reencode converts decoded JSON (maps/slices) into a typed value via a JSON round-trip.\nfunc reencode(raw any, target any) error {\n\tdata, err := json.Marshal(raw)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn json.Unmarshal(data, target)\n}\n\ntype pageCall func(params url.Values) (any, *http.Response, error)\n\n// iterPages yields raw page JSON per the pagination spec — the same stop\n// conditions and infinite-loop guards as the TypeScript runtime. The returned\n// function is a range-over-func iterator (Go 1.23+) and plainly callable before that.\nfunc iterPages(call pageCall, spec PaginationSpec, base url.Values) func(yield func(any, error) bool) {\n\treturn func(yield func(any, error) bool) {\n\t\tswitch spec.Style {\n\t\tcase "cursor":\n\t\t\tvar cursor any\n\t\t\tif values, ok := base[spec.Param]; ok && len(values) > 0 {\n\t\t\t\tcursor = values[0]\n\t\t\t}\n\t\t\tfor {\n\t\t\t\tparams := cloneValues(base)\n\t\t\t\tif cursor != nil {\n\t\t\t\t\tparams.Set(spec.Param, fmt.Sprint(cursor))\n\t\t\t\t}\n\t\t\t\tpage, _, err := call(params)\n\t\t\t\tif err != nil {\n\t\t\t\t\tyield(nil, err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif !yield(page, nil) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif spec.HasMore != "" {\n\t\t\t\t\tif more, ok := resolvePointer(page, spec.HasMore).(bool); ok && !more {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnext := resolvePointer(page, spec.NextCursor)\n\t\t\t\tif next == nil || next == "" {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tswitch next.(type) {\n\t\t\t\tcase string, float64:\n\t\t\t\tdefault:\n\t\t\t\t\tyield(nil, fmt.Errorf("pagination cursor at %s is not a string or number", spec.NextCursor))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif cursor != nil && fmt.Sprint(next) == fmt.Sprint(cursor) {\n\t\t\t\t\tyield(nil, errors.New("pagination did not advance: the operation returned the same cursor twice"))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcursor = next\n\t\t\t}\n\t\tcase "link":\n\t\t\tparams := cloneValues(base)\n\t\t\tprevious := ""\n\t\t\tfor {\n\t\t\t\tpage, resp, err := call(params)\n\t\t\t\tif err != nil {\n\t\t\t\t\tyield(nil, err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif !yield(page, nil) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ttarget := linkNext(resp.Header.Get("Link"))\n\t\t\t\tif target == "" {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tpageURL := ""\n\t\t\t\tif resp.Request != nil && resp.Request.URL != nil {\n\t\t\t\t\tpageURL = resp.Request.URL.String()\n\t\t\t\t}\n\t\t\t\tbaseURL, err := url.Parse(pageURL)\n\t\t\t\tif err != nil || pageURL == "" {\n\t\t\t\t\tbaseURL, _ = url.Parse("http://relative.invalid")\n\t\t\t\t}\n\t\t\t\ttargetURL, err := baseURL.Parse(target)\n\t\t\t\tif err != nil {\n\t\t\t\t\tyield(nil, err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tnext := targetURL.String()\n\t\t\t\tif next == previous || next == pageURL {\n\t\t\t\t\tyield(nil, errors.New(`pagination did not advance: the Link rel="next" target repeats`))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tprevious = next\n\t\t\t\tparams = cloneValues(base)\n\t\t\t\tfor key, values := range targetURL.Query() {\n\t\t\t\t\tfor _, value := range values {\n\t\t\t\t\t\tparams.Add(key, value)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tdefault: // offset / page\n\t\t\tposition := 0\n\t\t\tif spec.Style == "page" {\n\t\t\t\tposition = 1\n\t\t\t}\n\t\t\tif values, ok := base[spec.Param]; ok && len(values) > 0 && values[0] != "" {\n\t\t\t\tif parsed, err := strconv.Atoi(values[0]); err == nil {\n\t\t\t\t\tposition = parsed\n\t\t\t\t}\n\t\t\t}\n\t\t\tpreviousItems := ""\n\t\t\tfor {\n\t\t\t\tparams := cloneValues(base)\n\t\t\t\tparams.Set(spec.Param, strconv.Itoa(position))\n\t\t\t\tpage, _, err := call(params)\n\t\t\t\tif err != nil {\n\t\t\t\t\tyield(nil, err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\titems, _ := resolvePointer(page, spec.Items).([]any)\n\t\t\t\tserialized := ""\n\t\t\t\tif items != nil {\n\t\t\t\t\tserialized = fmt.Sprint(items)\n\t\t\t\t\tif serialized == previousItems {\n\t\t\t\t\t\tyield(nil, errors.New("pagination did not advance: the operation returned the same page twice"))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif !yield(page, nil) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif len(items) == 0 {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tpreviousItems = serialized\n\t\t\t\tif spec.Style == "page" {\n\t\t\t\t\tposition++\n\t\t\t\t} else {\n\t\t\t\t\tposition += len(items)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc cloneValues(values url.Values) url.Values {\n\tout := url.Values{}\n\tfor key, entries := range values {\n\t\tfor _, entry := range entries {\n\t\t\tout.Add(key, entry)\n\t\t}\n\t}\n\treturn out\n}\n\nfunc linkNext(header string) string {\n\tif header == "" {\n\t\treturn ""\n\t}\n\tfor _, entry := range strings.Split(header, ",") {\n\t\tparts := strings.Split(entry, ";")\n\t\tif len(parts) < 2 {\n\t\t\tcontinue\n\t\t}\n\t\ttarget := strings.TrimSpace(parts[0])\n\t\tif !strings.HasPrefix(target, "<") || !strings.HasSuffix(target, ">") {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, param := range parts[1:] {\n\t\t\ttrimmed := strings.TrimSpace(param)\n\t\t\tif strings.HasPrefix(trimmed, "rel=") {\n\t\t\t\trel := strings.Trim(strings.TrimPrefix(trimmed, "rel="), `"`)\n\t\t\t\tfor _, kind := range strings.Fields(rel) {\n\t\t\t\t\tif kind == "next" {\n\t\t\t\t\t\treturn strings.Trim(target, "<>")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn ""\n}\n\n// ─── Server-Sent Events ───\n\n// ServerSentEvent is one decoded event; Data is the raw text (or parsed JSON\n// for operations that declare a JSON event stream).\ntype ServerSentEvent struct {\n\tEvent string\n\tData any\n\tID string\n\tRetry int\n}\n\nfunc parseSSEFrame(raw string, jsonData bool) (ServerSentEvent, bool, error) {\n\tevent := ServerSentEvent{Retry: -1}\n\tsawField := false\n\tvar dataLines []string\n\tnormalized := strings.ReplaceAll(strings.ReplaceAll(raw, "\\r\\n", "\\n"), "\\r", "\\n")\n\tfor _, line := range strings.Split(normalized, "\\n") {\n\t\tif line == "" || strings.HasPrefix(line, ":") {\n\t\t\tcontinue\n\t\t}\n\t\tfield, value, _ := strings.Cut(line, ":")\n\t\tvalue = strings.TrimPrefix(value, " ")\n\t\tsawField = true\n\t\tswitch field {\n\t\tcase "event":\n\t\t\tevent.Event = value\n\t\tcase "data":\n\t\t\tdataLines = append(dataLines, value)\n\t\tcase "id":\n\t\t\tevent.ID = value\n\t\tcase "retry":\n\t\t\tif parsed, err := strconv.Atoi(value); err == nil && parsed >= 0 && value != "" {\n\t\t\t\tevent.Retry = parsed\n\t\t\t}\n\t\t}\n\t}\n\tif !sawField {\n\t\treturn event, false, nil\n\t}\n\ttext := strings.Join(dataLines, "\\n")\n\tevent.Data = text\n\tif jsonData && text != "" {\n\t\tvar parsed any\n\t\tif err := json.Unmarshal([]byte(text), &parsed); err != nil {\n\t\t\treturn event, false, err\n\t\t}\n\t\tevent.Data = parsed\n\t}\n\treturn event, true, nil\n}\n\n// iterSSE streams events, reconnecting on dropped connections with Last-Event-ID\n// (a fresh open call = fresh auth); a 4xx/5xx or a bad JSON payload is definitive.\nfunc iterSSE(open func(extraHeaders map[string]string) (*http.Response, error), jsonData bool) func(yield func(ServerSentEvent, error) bool) {\n\treturn func(yield func(ServerSentEvent, error) bool) {\n\t\tlastEventID := ""\n\t\tserverRetry := -1\n\t\tfailures := 0\n\t\tfor {\n\t\t\theaders := map[string]string{"Accept": "text/event-stream"}\n\t\t\tif lastEventID != "" {\n\t\t\t\theaders["Last-Event-ID"] = lastEventID\n\t\t\t}\n\t\t\tresp, err := open(headers)\n\t\t\tif err == nil && resp.StatusCode >= 400 {\n\t\t\t\tyield(ServerSentEvent{}, apiErrorFrom(resp, ""))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err == nil {\n\t\t\t\tfailures = 0\n\t\t\t\tbuffer := ""\n\t\t\t\tchunk := make([]byte, 4096)\n\t\t\t\tclean := false\n\t\t\t\tfor {\n\t\t\t\t\tn, readErr := resp.Body.Read(chunk)\n\t\t\t\t\tbuffer += string(chunk[:n])\n\t\t\t\t\tfor {\n\t\t\t\t\t\tframe, rest, found := strings.Cut(buffer, "\\n\\n")\n\t\t\t\t\t\tif !found {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbuffer = rest\n\t\t\t\t\t\tevent, ok, parseErr := parseSSEFrame(frame, jsonData)\n\t\t\t\t\t\tif parseErr != nil {\n\t\t\t\t\t\t\tresp.Body.Close()\n\t\t\t\t\t\t\tyield(ServerSentEvent{}, parseErr)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ok {\n\t\t\t\t\t\t\tif event.ID != "" {\n\t\t\t\t\t\t\t\tlastEventID = event.ID\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif event.Retry >= 0 {\n\t\t\t\t\t\t\t\tserverRetry = event.Retry\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif !yield(event, nil) {\n\t\t\t\t\t\t\t\tresp.Body.Close()\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif readErr == io.EOF {\n\t\t\t\t\t\tclean = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tif readErr != nil {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresp.Body.Close()\n\t\t\t\tif clean {\n\t\t\t\t\tif strings.TrimSpace(buffer) != "" {\n\t\t\t\t\t\tif event, ok, parseErr := parseSSEFrame(buffer, jsonData); parseErr == nil && ok {\n\t\t\t\t\t\t\tyield(event, nil)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tfailures++\n\t\t\tbase := time.Second\n\t\t\tif serverRetry >= 0 {\n\t\t\t\tbase = time.Duration(serverRetry) * time.Millisecond\n\t\t\t}\n\t\t\tdelay := base * time.Duration(1<<(failures-1))\n\t\t\tif delay > 30*time.Second {\n\t\t\t\tdelay = 30 * time.Second\n\t\t\t}\n\t\t\ttime.Sleep(time.Duration(rand.Int63n(int64(delay) + 1)))\n\t\t}\n\t}\n}\n\n// ─── Multipart ───\n\n// toMultipart splits a typed body into a multipart/form-data payload: []byte\n// values upload as file parts, everything else as form fields (nested values\n// JSON-encoded) — mirroring the TypeScript runtime\'s FormData serialization.\nfunc toMultipart(body any) (string, io.Reader, error) {\n\tvar wire map[string]any\n\tif err := reencode(body, &wire); err != nil {\n\t\treturn "", nil, err\n\t}\n\tbuffer := &bytes.Buffer{}\n\twriter := multipart.NewWriter(buffer)\n\tfor key, value := range wire {\n\t\tswitch typed := value.(type) {\n\t\tcase string:\n\t\t\tif err := writer.WriteField(key, typed); err != nil {\n\t\t\t\treturn "", nil, err\n\t\t\t}\n\t\tcase float64, bool:\n\t\t\tif err := writer.WriteField(key, fmt.Sprint(typed)); err != nil {\n\t\t\t\treturn "", nil, err\n\t\t\t}\n\t\tdefault:\n\t\t\tencoded, err := json.Marshal(typed)\n\t\t\tif err != nil {\n\t\t\t\treturn "", nil, err\n\t\t\t}\n\t\t\tif err := writer.WriteField(key, string(encoded)); err != nil {\n\t\t\t\treturn "", nil, err\n\t\t\t}\n\t\t}\n\t}\n\tif err := writer.Close(); err != nil {\n\t\treturn "", nil, err\n\t}\n\treturn writer.FormDataContentType(), buffer, nil\n}\n';
|
|
3
|
+
//# sourceMappingURL=go.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go.js","sourceRoot":"","sources":["../../src/runtime-sources/go.ts"],"names":[],"mappings":"AAAA,iKAAiK;AACjK,MAAM,CAAC,MAAM,iBAAiB,GAC5B,y5wBAAy5wB,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const PHP_RUNTIME_SOURCE = "<?php\n\n// @redocly/client-generator PHP runtime \u2014 embedded into generated clients.\n// PHP >= 8.1, zero Composer dependencies; HTTP over the curl extension.\n// The generated file re-declares the namespace; the embed strips this header.\n\ndeclare(strict_types=1);\n\nnamespace RedoclyClientRuntime;\n\n/** A response with status >= 400, decoded body attached. */\nfinal class ApiError extends \\RuntimeException\n{\n public function __construct(\n public readonly string $url,\n public readonly int $status,\n public readonly string $reason,\n public readonly mixed $body,\n ) {\n parent::__construct(\"HTTP {$status} {$reason} for {$url}\");\n }\n}\n\n/** Every attempt timed out or failed to connect. */\nfinal class TimeoutError extends \\RuntimeException\n{\n public function __construct(\n public readonly string $url,\n public readonly ?float $timeout,\n public readonly int $attempts,\n ) {\n $seconds = $timeout === null ? 'the configured timeout' : \"{$timeout}s\";\n parent::__construct(\"Request to {$url} timed out after {$seconds} ({$attempts} attempt(s))\");\n }\n}\n\n/** One parsed `text/event-stream` frame. */\n/** A `<op>WithHeaders()` result: the decoded body plus coerced declared headers. */\nfinal class Envelope\n{\n public function __construct(\n public readonly mixed $data,\n public readonly array $headers,\n public readonly int $status,\n ) {\n }\n}\n\n/** Coerce declared response headers per `[name, key, type]` specs; absent/unparsable omitted. */\nfunction readEnvelopeHeaders(array $response, array $specs): array\n{\n $headers = [];\n foreach ($specs as [$name, $key, $type]) {\n $raw = $response['headers'][$name] ?? null;\n if ($raw === null) {\n continue;\n }\n if ($type === 'integer' || $type === 'number') {\n if (is_numeric($raw)) {\n $headers[$key] = $type === 'integer' ? (int) $raw : (float) $raw;\n }\n } elseif ($type === 'boolean') {\n $lower = strtolower(trim($raw));\n if ($lower === 'true' || $lower === 'false') {\n $headers[$key] = $lower === 'true';\n }\n } else {\n $headers[$key] = $raw;\n }\n }\n return $headers;\n}\n\nfinal class ServerSentEvent\n{\n public function __construct(\n public readonly string $event,\n public readonly mixed $data,\n public readonly ?string $id = null,\n public readonly ?int $retry = null,\n ) {\n }\n}\n\n/**\n * Per-instance configuration.\n * `auth`: `['bearer' => string|callable, 'basic' => ['username' => ..., 'password' => ...], 'apiKey' => [scheme => string|callable]]`.\n * `retry`: `['attempts' => int, 'delay' => float, 'strategy' => 'exponential'|'fixed', 'retryOn' => callable]`.\n * `middleware`: callables `fn(array $request, callable $next): array` around each attempt.\n */\nfinal class Config\n{\n public function __construct(\n public string $serverUrl = '',\n public array $auth = [],\n public ?float $timeout = null,\n public array $retry = [],\n public array $middleware = [],\n public string $clientHeader = 'redocly-client-generator',\n ) {\n }\n}\n\n/** Resolve a literal-or-callable credential to its string value. */\nfunction resolveToken(mixed $provider): string\n{\n return is_callable($provider) ? (string) $provider() : (string) $provider;\n}\n\n/**\n * Apply the first fully-configured security alternative. `$security` is an OR-list\n * of AND-sets of specs: `['kind' => 'bearer'|'basic'|'apiKey', 'scheme' => ..., 'name' => ?, 'in' => ?]`.\n * Returns `[headers, query, cookies]`.\n */\nfunction resolveAuth(array $security, array $auth): array\n{\n foreach ($security as $andSet) {\n $headers = [];\n $query = [];\n $cookies = [];\n $satisfied = true;\n foreach ($andSet as $spec) {\n if ($spec['kind'] === 'bearer' && isset($auth['bearer'])) {\n $headers['Authorization'] = 'Bearer ' . resolveToken($auth['bearer']);\n } elseif ($spec['kind'] === 'basic' && isset($auth['basic'])) {\n $headers['Authorization'] =\n 'Basic ' . base64_encode($auth['basic']['username'] . ':' . $auth['basic']['password']);\n } elseif ($spec['kind'] === 'apiKey' && isset($auth['apiKey'][$spec['scheme']])) {\n $value = resolveToken($auth['apiKey'][$spec['scheme']]);\n if ($spec['in'] === 'query') {\n $query[$spec['name']] = $value;\n } elseif ($spec['in'] === 'cookie') {\n $cookies[] = $spec['name'] . '=' . rawurlencode($value);\n } else {\n $headers[$spec['name']] = $value;\n }\n } else {\n $satisfied = false;\n break;\n }\n }\n if ($satisfied) {\n return [$headers, $query, $cookies];\n }\n }\n return [[], [], []];\n}\n\n/** Substitute `{param}` templates with encoded values and prefix the server URL. */\nfunction buildUrl(string $serverUrl, string $path, array $pathParams): string\n{\n foreach ($pathParams as $name => $value) {\n $path = str_replace('{' . $name . '}', rawurlencode((string) $value), $path);\n }\n return rtrim($serverUrl, '/') . $path;\n}\n\n/** The default retry predicate: 5xx, 429, and transport timeouts/connect failures. */\nfunction defaultRetryOn(array $context): bool\n{\n if (($context['timedOut'] ?? false) === true) {\n return true;\n }\n $status = $context['status'] ?? 0;\n return $status >= 500 || $status === 429;\n}\n\n/** Delay before the next attempt: `Retry-After` wins; otherwise jittered (fixed|exponential) backoff. */\nfunction retryDelay(int $attempt, array $retry, ?string $retryAfter): float\n{\n if ($retryAfter !== null && ctype_digit($retryAfter)) {\n return (float) $retryAfter;\n }\n $base = (float) ($retry['delay'] ?? 1.0);\n $strategy = $retry['strategy'] ?? 'exponential';\n $delay = $strategy === 'fixed' ? $base : $base * (2 ** ($attempt - 1));\n return $delay * (0.5 + mt_rand() / mt_getrandmax() / 2);\n}\n\n/** Append query params in form style: list values repeat the key (`tag=a&tag=b`). */\nfunction appendQuery(string $url, array $query): string\n{\n $pairs = [];\n foreach ($query as $name => $value) {\n foreach (is_array($value) ? $value : [$value] as $single) {\n $encoded = is_bool($single) ? ($single ? 'true' : 'false') : (string) $single;\n $pairs[] = rawurlencode($name) . '=' . rawurlencode($encoded);\n }\n }\n if ($pairs === []) {\n return $url;\n }\n return $url . (str_contains($url, '?') ? '&' : '?') . implode('&', $pairs);\n}\n\n/** One raw curl exchange. Returns `['status', 'reason', 'headers', 'body', 'url', 'timedOut']`. */\nfunction rawSend(Config $config, array $request): array\n{\n $url = appendQuery($request['url'], $request['query'] ?? []);\n $handle = curl_init($url);\n $headerLines = [];\n foreach ($request['headers'] ?? [] as $name => $value) {\n $headerLines[] = $name . ': ' . $value;\n }\n $responseHeaders = [];\n curl_setopt_array($handle, [\n CURLOPT_CUSTOMREQUEST => $request['method'],\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_HTTPHEADER => $headerLines,\n CURLOPT_HEADERFUNCTION => function ($ch, string $line) use (&$responseHeaders): int {\n $parts = explode(':', $line, 2);\n if (count($parts) === 2) {\n $responseHeaders[strtolower(trim($parts[0]))] = trim($parts[1]);\n }\n return strlen($line);\n },\n ]);\n if (($request['body'] ?? null) !== null) {\n curl_setopt($handle, CURLOPT_POSTFIELDS, $request['body']);\n }\n if ($config->timeout !== null) {\n curl_setopt($handle, CURLOPT_TIMEOUT_MS, (int) round($config->timeout * 1000));\n }\n $body = curl_exec($handle);\n $errno = curl_errno($handle);\n $status = (int) curl_getinfo($handle, CURLINFO_RESPONSE_CODE);\n $effectiveUrl = (string) curl_getinfo($handle, CURLINFO_EFFECTIVE_URL);\n if ($errno !== 0) {\n $timedOut = $errno === CURLE_OPERATION_TIMEDOUT || $errno === CURLE_COULDNT_CONNECT;\n return [\n 'status' => 0,\n 'reason' => curl_strerror($errno) ?? 'transport error',\n 'headers' => [],\n 'body' => '',\n 'url' => $effectiveUrl,\n 'timedOut' => $timedOut,\n ];\n }\n return [\n 'status' => $status,\n 'reason' => '',\n 'headers' => $responseHeaders,\n 'body' => is_string($body) ? $body : '',\n 'url' => $effectiveUrl,\n 'timedOut' => false,\n ];\n}\n\n/**\n * Send with retries and middleware. `$request` carries `operationId`, `method`, `url`,\n * `headers`, `query`, and optional `body`/`contentType`/`idempotencyKey`.\n * Returns the raw response array; callers map status >= 400 to `ApiError`.\n */\nfunction send(Config $config, array $request): array\n{\n $headers = $request['headers'] ?? [];\n $headers['X-Redocly-Client'] = $config->clientHeader;\n if (($request['contentType'] ?? null) !== null) {\n $headers['Content-Type'] = $request['contentType'];\n }\n if (($request['idempotencyKey'] ?? null) !== null) {\n $headers['Idempotency-Key'] = $request['idempotencyKey'];\n }\n $request['headers'] = $headers;\n\n $handler = fn (array $req): array => rawSend($config, $req);\n foreach (array_reverse($config->middleware) as $middleware) {\n $next = $handler;\n $handler = fn (array $req): array => $middleware($req, $next);\n }\n\n $attempts = max(1, (int) ($config->retry['attempts'] ?? 3));\n $retryOn = $config->retry['retryOn'] ?? __NAMESPACE__ . '\\\\defaultRetryOn';\n $response = null;\n for ($attempt = 1; $attempt <= $attempts; $attempt++) {\n $response = $handler($request);\n $context = [\n 'status' => $response['status'],\n 'timedOut' => $response['timedOut'],\n 'attempt' => $attempt,\n 'operationId' => $request['operationId'] ?? '',\n ];\n if ($attempt === $attempts || !$retryOn($context)) {\n break;\n }\n $seconds = retryDelay($attempt, $config->retry, $response['headers']['retry-after'] ?? null);\n usleep((int) round($seconds * 1_000_000));\n }\n if ($response['timedOut']) {\n throw new TimeoutError($response['url'], $config->timeout, $attempts);\n }\n if ($response['status'] === 0) {\n throw new \\RuntimeException(\"Request to {$response['url']} failed: {$response['reason']}\");\n }\n return $response;\n}\n\n/** Decoded JSON body (assoc arrays), or null for empty bodies. */\nfunction decodeJson(array $response): mixed\n{\n if ($response['body'] === '') {\n return null;\n }\n return json_decode($response['body'], true);\n}\n\n/** `ApiError` from a non-2xx response. */\nfunction apiErrorFrom(array $response): ApiError\n{\n return new ApiError($response['url'], $response['status'], $response['reason'], decodeJson($response));\n}\n\n/** Walk an RFC 6901 JSON pointer over decoded JSON; null on any miss. */\nfunction resolvePointer(mixed $data, string $pointer): mixed\n{\n if ($pointer === '') {\n return $data;\n }\n foreach (explode('/', substr($pointer, 1)) as $token) {\n $key = str_replace(['~1', '~0'], ['/', '~'], $token);\n if (!is_array($data) || !array_key_exists($key, $data)) {\n return null;\n }\n $data = $data[$key];\n }\n return $data;\n}\n\n/** The `rel=\"next\"` target of a `Link` header, or null. */\nfunction linkNext(?string $header): ?string\n{\n if ($header === null) {\n return null;\n }\n foreach (explode(',', $header) as $part) {\n if (preg_match('/<([^>]+)>\\s*;[^,]*rel=\"?next\"?/', trim($part), $match) === 1) {\n return $match[1];\n }\n }\n return null;\n}\n\n/**\n * Auto-pagination: `$call(array $params): [mixed rawPage, array $response]`, `$spec` is the\n * normalized rule (`style`, `param`, `nextCursor`, `hasMore`, `items`), `$base` the caller's\n * query params. Yields raw decoded pages; generated wrappers hydrate them into models.\n */\nfunction iterPages(callable $call, array $spec, array $base): \\Generator\n{\n $params = $base;\n $style = $spec['style'];\n $seenCursors = [];\n $seenLinks = [];\n $offset = null;\n $page = null;\n while (true) {\n [$raw, $response] = $call($params);\n yield $raw;\n if ($style === 'cursor') {\n $next = resolvePointer($raw, $spec['nextCursor'] ?? '');\n if (isset($spec['hasMore']) && resolvePointer($raw, $spec['hasMore']) !== true) {\n return;\n }\n if (!is_string($next) || $next === '' || isset($seenCursors[$next])) {\n return;\n }\n $seenCursors[$next] = true;\n $params[$spec['param']] = $next;\n } elseif ($style === 'link') {\n $target = linkNext($response['headers']['link'] ?? null);\n if ($target === null || isset($seenLinks[$target])) {\n return;\n }\n $seenLinks[$target] = true;\n $parsed = parse_url($target);\n $linkParams = [];\n parse_str($parsed['query'] ?? '', $linkParams);\n $params = array_merge($params, $linkParams);\n } else {\n $items = resolvePointer($raw, $spec['items'] ?? '');\n $count = is_array($items) ? count($items) : 0;\n if ($count === 0) {\n return;\n }\n if ($style === 'offset') {\n $offset = ($offset ?? (int) ($base[$spec['param']] ?? 0)) + $count;\n $params[$spec['param']] = $offset;\n } else {\n $page = ($page ?? (int) ($base[$spec['param']] ?? 1)) + 1;\n $params[$spec['param']] = $page;\n }\n }\n }\n}\n\n/** Parse one SSE frame; returns `[?ServerSentEvent, ?string lastEventId, ?int retryMs]`. */\nfunction parseSseFrame(string $frame, bool $jsonData): array\n{\n $event = 'message';\n $dataLines = [];\n $id = null;\n $retry = null;\n foreach (explode(\"\\n\", str_replace(\"\\r\\n\", \"\\n\", $frame)) as $line) {\n if ($line === '' || str_starts_with($line, ':')) {\n continue;\n }\n $colon = strpos($line, ':');\n $field = $colon === false ? $line : substr($line, 0, $colon);\n $value = $colon === false ? '' : ltrim(substr($line, $colon + 1), ' ');\n if ($field === 'event') {\n $event = $value;\n } elseif ($field === 'data') {\n $dataLines[] = $value;\n } elseif ($field === 'id') {\n $id = $value;\n } elseif ($field === 'retry' && ctype_digit($value)) {\n $retry = (int) $value;\n }\n }\n if ($dataLines === [] && $id === null && $retry === null) {\n return [null, null, $retry];\n }\n $data = implode(\"\\n\", $dataLines);\n $decoded = $jsonData && $data !== '' ? json_decode($data, true) : $data;\n return [new ServerSentEvent($event, $decoded, $id, $retry), $id, $retry];\n}\n\n/**\n * Stream server-sent events. `$open(array $extraHeaders): \\CurlHandle` returns a configured\n * (not yet executed) handle; this pump drives it with curl_multi, yields parsed frames, and\n * reconnects with `Last-Event-ID` on transient failures (4xx is definitive; backoff <= 30s).\n */\nfunction iterSse(callable $open, bool $jsonData): \\Generator\n{\n $lastEventId = null;\n $retryMs = 3000;\n while (true) {\n $extra = ['Accept' => 'text/event-stream'];\n if ($lastEventId !== null) {\n $extra['Last-Event-ID'] = $lastEventId;\n }\n $handle = $open($extra);\n $buffer = '';\n curl_setopt($handle, CURLOPT_WRITEFUNCTION, function ($ch, string $chunk) use (&$buffer): int {\n $buffer .= $chunk;\n return strlen($chunk);\n });\n $multi = curl_multi_init();\n curl_multi_add_handle($multi, $handle);\n do {\n curl_multi_exec($multi, $running);\n if ($running > 0) {\n curl_multi_select($multi, 0.1);\n }\n while (($split = strpos($buffer, \"\\n\\n\")) !== false || ($split = strpos($buffer, \"\\r\\n\\r\\n\")) !== false) {\n $frameLength = $buffer[$split] === \"\\r\" ? 4 : 2;\n $frame = substr($buffer, 0, $split);\n $buffer = substr($buffer, $split + $frameLength);\n [$event, $id, $retry] = parseSseFrame($frame, $jsonData);\n if ($id !== null) {\n $lastEventId = $id;\n }\n if ($retry !== null) {\n $retryMs = min($retry, 30000);\n }\n if ($event !== null) {\n yield $event;\n }\n }\n } while ($running > 0);\n $status = (int) curl_getinfo($handle, CURLINFO_RESPONSE_CODE);\n $url = (string) curl_getinfo($handle, CURLINFO_EFFECTIVE_URL);\n curl_multi_remove_handle($multi, $handle);\n curl_multi_close($multi);\n if ($status >= 400 && $status < 500) {\n throw new ApiError($url, $status, '', $buffer);\n }\n // A clean 200 end-of-stream is done; anything else reconnects with Last-Event-ID.\n if ($status === 200) {\n return;\n }\n usleep($retryMs * 1000);\n }\n}\n\n/** Encode an assoc body as `multipart/form-data`; nested values are JSON parts. Returns `[contentType, body]`. */\nfunction toMultipart(array $body): array\n{\n $boundary = 'redocly-' . bin2hex(random_bytes(12));\n $parts = '';\n foreach ($body as $name => $value) {\n $parts .= \"--{$boundary}\\r\\n\";\n if (is_array($value)) {\n $parts .= \"Content-Disposition: form-data; name=\\\"{$name}\\\"\\r\\n\";\n $parts .= \"Content-Type: application/json\\r\\n\\r\\n\";\n $parts .= json_encode($value) . \"\\r\\n\";\n } else {\n $parts .= \"Content-Disposition: form-data; name=\\\"{$name}\\\"\\r\\n\\r\\n\";\n $parts .= (is_bool($value) ? ($value ? 'true' : 'false') : (string) $value) . \"\\r\\n\";\n }\n }\n $parts .= \"--{$boundary}--\\r\\n\";\n return ['multipart/form-data; boundary=' . $boundary, $parts];\n}\n";
|
|
2
|
+
//# sourceMappingURL=php.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"php.d.ts","sourceRoot":"","sources":["../../src/runtime-sources/php.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,kBAAkB,w/kBACm9kB,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// GENERATED by scripts/generate-runtime-sources.mjs — do not edit. Regenerated on install (`prepare`); manually: `npm run prepare -w @redocly/client-generator`.
|
|
2
|
+
export const PHP_RUNTIME_SOURCE = "<?php\n\n// @redocly/client-generator PHP runtime — embedded into generated clients.\n// PHP >= 8.1, zero Composer dependencies; HTTP over the curl extension.\n// The generated file re-declares the namespace; the embed strips this header.\n\ndeclare(strict_types=1);\n\nnamespace RedoclyClientRuntime;\n\n/** A response with status >= 400, decoded body attached. */\nfinal class ApiError extends \\RuntimeException\n{\n public function __construct(\n public readonly string $url,\n public readonly int $status,\n public readonly string $reason,\n public readonly mixed $body,\n ) {\n parent::__construct(\"HTTP {$status} {$reason} for {$url}\");\n }\n}\n\n/** Every attempt timed out or failed to connect. */\nfinal class TimeoutError extends \\RuntimeException\n{\n public function __construct(\n public readonly string $url,\n public readonly ?float $timeout,\n public readonly int $attempts,\n ) {\n $seconds = $timeout === null ? 'the configured timeout' : \"{$timeout}s\";\n parent::__construct(\"Request to {$url} timed out after {$seconds} ({$attempts} attempt(s))\");\n }\n}\n\n/** One parsed `text/event-stream` frame. */\n/** A `<op>WithHeaders()` result: the decoded body plus coerced declared headers. */\nfinal class Envelope\n{\n public function __construct(\n public readonly mixed $data,\n public readonly array $headers,\n public readonly int $status,\n ) {\n }\n}\n\n/** Coerce declared response headers per `[name, key, type]` specs; absent/unparsable omitted. */\nfunction readEnvelopeHeaders(array $response, array $specs): array\n{\n $headers = [];\n foreach ($specs as [$name, $key, $type]) {\n $raw = $response['headers'][$name] ?? null;\n if ($raw === null) {\n continue;\n }\n if ($type === 'integer' || $type === 'number') {\n if (is_numeric($raw)) {\n $headers[$key] = $type === 'integer' ? (int) $raw : (float) $raw;\n }\n } elseif ($type === 'boolean') {\n $lower = strtolower(trim($raw));\n if ($lower === 'true' || $lower === 'false') {\n $headers[$key] = $lower === 'true';\n }\n } else {\n $headers[$key] = $raw;\n }\n }\n return $headers;\n}\n\nfinal class ServerSentEvent\n{\n public function __construct(\n public readonly string $event,\n public readonly mixed $data,\n public readonly ?string $id = null,\n public readonly ?int $retry = null,\n ) {\n }\n}\n\n/**\n * Per-instance configuration.\n * `auth`: `['bearer' => string|callable, 'basic' => ['username' => ..., 'password' => ...], 'apiKey' => [scheme => string|callable]]`.\n * `retry`: `['attempts' => int, 'delay' => float, 'strategy' => 'exponential'|'fixed', 'retryOn' => callable]`.\n * `middleware`: callables `fn(array $request, callable $next): array` around each attempt.\n */\nfinal class Config\n{\n public function __construct(\n public string $serverUrl = '',\n public array $auth = [],\n public ?float $timeout = null,\n public array $retry = [],\n public array $middleware = [],\n public string $clientHeader = 'redocly-client-generator',\n ) {\n }\n}\n\n/** Resolve a literal-or-callable credential to its string value. */\nfunction resolveToken(mixed $provider): string\n{\n return is_callable($provider) ? (string) $provider() : (string) $provider;\n}\n\n/**\n * Apply the first fully-configured security alternative. `$security` is an OR-list\n * of AND-sets of specs: `['kind' => 'bearer'|'basic'|'apiKey', 'scheme' => ..., 'name' => ?, 'in' => ?]`.\n * Returns `[headers, query, cookies]`.\n */\nfunction resolveAuth(array $security, array $auth): array\n{\n foreach ($security as $andSet) {\n $headers = [];\n $query = [];\n $cookies = [];\n $satisfied = true;\n foreach ($andSet as $spec) {\n if ($spec['kind'] === 'bearer' && isset($auth['bearer'])) {\n $headers['Authorization'] = 'Bearer ' . resolveToken($auth['bearer']);\n } elseif ($spec['kind'] === 'basic' && isset($auth['basic'])) {\n $headers['Authorization'] =\n 'Basic ' . base64_encode($auth['basic']['username'] . ':' . $auth['basic']['password']);\n } elseif ($spec['kind'] === 'apiKey' && isset($auth['apiKey'][$spec['scheme']])) {\n $value = resolveToken($auth['apiKey'][$spec['scheme']]);\n if ($spec['in'] === 'query') {\n $query[$spec['name']] = $value;\n } elseif ($spec['in'] === 'cookie') {\n $cookies[] = $spec['name'] . '=' . rawurlencode($value);\n } else {\n $headers[$spec['name']] = $value;\n }\n } else {\n $satisfied = false;\n break;\n }\n }\n if ($satisfied) {\n return [$headers, $query, $cookies];\n }\n }\n return [[], [], []];\n}\n\n/** Substitute `{param}` templates with encoded values and prefix the server URL. */\nfunction buildUrl(string $serverUrl, string $path, array $pathParams): string\n{\n foreach ($pathParams as $name => $value) {\n $path = str_replace('{' . $name . '}', rawurlencode((string) $value), $path);\n }\n return rtrim($serverUrl, '/') . $path;\n}\n\n/** The default retry predicate: 5xx, 429, and transport timeouts/connect failures. */\nfunction defaultRetryOn(array $context): bool\n{\n if (($context['timedOut'] ?? false) === true) {\n return true;\n }\n $status = $context['status'] ?? 0;\n return $status >= 500 || $status === 429;\n}\n\n/** Delay before the next attempt: `Retry-After` wins; otherwise jittered (fixed|exponential) backoff. */\nfunction retryDelay(int $attempt, array $retry, ?string $retryAfter): float\n{\n if ($retryAfter !== null && ctype_digit($retryAfter)) {\n return (float) $retryAfter;\n }\n $base = (float) ($retry['delay'] ?? 1.0);\n $strategy = $retry['strategy'] ?? 'exponential';\n $delay = $strategy === 'fixed' ? $base : $base * (2 ** ($attempt - 1));\n return $delay * (0.5 + mt_rand() / mt_getrandmax() / 2);\n}\n\n/** Append query params in form style: list values repeat the key (`tag=a&tag=b`). */\nfunction appendQuery(string $url, array $query): string\n{\n $pairs = [];\n foreach ($query as $name => $value) {\n foreach (is_array($value) ? $value : [$value] as $single) {\n $encoded = is_bool($single) ? ($single ? 'true' : 'false') : (string) $single;\n $pairs[] = rawurlencode($name) . '=' . rawurlencode($encoded);\n }\n }\n if ($pairs === []) {\n return $url;\n }\n return $url . (str_contains($url, '?') ? '&' : '?') . implode('&', $pairs);\n}\n\n/** One raw curl exchange. Returns `['status', 'reason', 'headers', 'body', 'url', 'timedOut']`. */\nfunction rawSend(Config $config, array $request): array\n{\n $url = appendQuery($request['url'], $request['query'] ?? []);\n $handle = curl_init($url);\n $headerLines = [];\n foreach ($request['headers'] ?? [] as $name => $value) {\n $headerLines[] = $name . ': ' . $value;\n }\n $responseHeaders = [];\n curl_setopt_array($handle, [\n CURLOPT_CUSTOMREQUEST => $request['method'],\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_HTTPHEADER => $headerLines,\n CURLOPT_HEADERFUNCTION => function ($ch, string $line) use (&$responseHeaders): int {\n $parts = explode(':', $line, 2);\n if (count($parts) === 2) {\n $responseHeaders[strtolower(trim($parts[0]))] = trim($parts[1]);\n }\n return strlen($line);\n },\n ]);\n if (($request['body'] ?? null) !== null) {\n curl_setopt($handle, CURLOPT_POSTFIELDS, $request['body']);\n }\n if ($config->timeout !== null) {\n curl_setopt($handle, CURLOPT_TIMEOUT_MS, (int) round($config->timeout * 1000));\n }\n $body = curl_exec($handle);\n $errno = curl_errno($handle);\n $status = (int) curl_getinfo($handle, CURLINFO_RESPONSE_CODE);\n $effectiveUrl = (string) curl_getinfo($handle, CURLINFO_EFFECTIVE_URL);\n if ($errno !== 0) {\n $timedOut = $errno === CURLE_OPERATION_TIMEDOUT || $errno === CURLE_COULDNT_CONNECT;\n return [\n 'status' => 0,\n 'reason' => curl_strerror($errno) ?? 'transport error',\n 'headers' => [],\n 'body' => '',\n 'url' => $effectiveUrl,\n 'timedOut' => $timedOut,\n ];\n }\n return [\n 'status' => $status,\n 'reason' => '',\n 'headers' => $responseHeaders,\n 'body' => is_string($body) ? $body : '',\n 'url' => $effectiveUrl,\n 'timedOut' => false,\n ];\n}\n\n/**\n * Send with retries and middleware. `$request` carries `operationId`, `method`, `url`,\n * `headers`, `query`, and optional `body`/`contentType`/`idempotencyKey`.\n * Returns the raw response array; callers map status >= 400 to `ApiError`.\n */\nfunction send(Config $config, array $request): array\n{\n $headers = $request['headers'] ?? [];\n $headers['X-Redocly-Client'] = $config->clientHeader;\n if (($request['contentType'] ?? null) !== null) {\n $headers['Content-Type'] = $request['contentType'];\n }\n if (($request['idempotencyKey'] ?? null) !== null) {\n $headers['Idempotency-Key'] = $request['idempotencyKey'];\n }\n $request['headers'] = $headers;\n\n $handler = fn (array $req): array => rawSend($config, $req);\n foreach (array_reverse($config->middleware) as $middleware) {\n $next = $handler;\n $handler = fn (array $req): array => $middleware($req, $next);\n }\n\n $attempts = max(1, (int) ($config->retry['attempts'] ?? 3));\n $retryOn = $config->retry['retryOn'] ?? __NAMESPACE__ . '\\\\defaultRetryOn';\n $response = null;\n for ($attempt = 1; $attempt <= $attempts; $attempt++) {\n $response = $handler($request);\n $context = [\n 'status' => $response['status'],\n 'timedOut' => $response['timedOut'],\n 'attempt' => $attempt,\n 'operationId' => $request['operationId'] ?? '',\n ];\n if ($attempt === $attempts || !$retryOn($context)) {\n break;\n }\n $seconds = retryDelay($attempt, $config->retry, $response['headers']['retry-after'] ?? null);\n usleep((int) round($seconds * 1_000_000));\n }\n if ($response['timedOut']) {\n throw new TimeoutError($response['url'], $config->timeout, $attempts);\n }\n if ($response['status'] === 0) {\n throw new \\RuntimeException(\"Request to {$response['url']} failed: {$response['reason']}\");\n }\n return $response;\n}\n\n/** Decoded JSON body (assoc arrays), or null for empty bodies. */\nfunction decodeJson(array $response): mixed\n{\n if ($response['body'] === '') {\n return null;\n }\n return json_decode($response['body'], true);\n}\n\n/** `ApiError` from a non-2xx response. */\nfunction apiErrorFrom(array $response): ApiError\n{\n return new ApiError($response['url'], $response['status'], $response['reason'], decodeJson($response));\n}\n\n/** Walk an RFC 6901 JSON pointer over decoded JSON; null on any miss. */\nfunction resolvePointer(mixed $data, string $pointer): mixed\n{\n if ($pointer === '') {\n return $data;\n }\n foreach (explode('/', substr($pointer, 1)) as $token) {\n $key = str_replace(['~1', '~0'], ['/', '~'], $token);\n if (!is_array($data) || !array_key_exists($key, $data)) {\n return null;\n }\n $data = $data[$key];\n }\n return $data;\n}\n\n/** The `rel=\"next\"` target of a `Link` header, or null. */\nfunction linkNext(?string $header): ?string\n{\n if ($header === null) {\n return null;\n }\n foreach (explode(',', $header) as $part) {\n if (preg_match('/<([^>]+)>\\s*;[^,]*rel=\"?next\"?/', trim($part), $match) === 1) {\n return $match[1];\n }\n }\n return null;\n}\n\n/**\n * Auto-pagination: `$call(array $params): [mixed rawPage, array $response]`, `$spec` is the\n * normalized rule (`style`, `param`, `nextCursor`, `hasMore`, `items`), `$base` the caller's\n * query params. Yields raw decoded pages; generated wrappers hydrate them into models.\n */\nfunction iterPages(callable $call, array $spec, array $base): \\Generator\n{\n $params = $base;\n $style = $spec['style'];\n $seenCursors = [];\n $seenLinks = [];\n $offset = null;\n $page = null;\n while (true) {\n [$raw, $response] = $call($params);\n yield $raw;\n if ($style === 'cursor') {\n $next = resolvePointer($raw, $spec['nextCursor'] ?? '');\n if (isset($spec['hasMore']) && resolvePointer($raw, $spec['hasMore']) !== true) {\n return;\n }\n if (!is_string($next) || $next === '' || isset($seenCursors[$next])) {\n return;\n }\n $seenCursors[$next] = true;\n $params[$spec['param']] = $next;\n } elseif ($style === 'link') {\n $target = linkNext($response['headers']['link'] ?? null);\n if ($target === null || isset($seenLinks[$target])) {\n return;\n }\n $seenLinks[$target] = true;\n $parsed = parse_url($target);\n $linkParams = [];\n parse_str($parsed['query'] ?? '', $linkParams);\n $params = array_merge($params, $linkParams);\n } else {\n $items = resolvePointer($raw, $spec['items'] ?? '');\n $count = is_array($items) ? count($items) : 0;\n if ($count === 0) {\n return;\n }\n if ($style === 'offset') {\n $offset = ($offset ?? (int) ($base[$spec['param']] ?? 0)) + $count;\n $params[$spec['param']] = $offset;\n } else {\n $page = ($page ?? (int) ($base[$spec['param']] ?? 1)) + 1;\n $params[$spec['param']] = $page;\n }\n }\n }\n}\n\n/** Parse one SSE frame; returns `[?ServerSentEvent, ?string lastEventId, ?int retryMs]`. */\nfunction parseSseFrame(string $frame, bool $jsonData): array\n{\n $event = 'message';\n $dataLines = [];\n $id = null;\n $retry = null;\n foreach (explode(\"\\n\", str_replace(\"\\r\\n\", \"\\n\", $frame)) as $line) {\n if ($line === '' || str_starts_with($line, ':')) {\n continue;\n }\n $colon = strpos($line, ':');\n $field = $colon === false ? $line : substr($line, 0, $colon);\n $value = $colon === false ? '' : ltrim(substr($line, $colon + 1), ' ');\n if ($field === 'event') {\n $event = $value;\n } elseif ($field === 'data') {\n $dataLines[] = $value;\n } elseif ($field === 'id') {\n $id = $value;\n } elseif ($field === 'retry' && ctype_digit($value)) {\n $retry = (int) $value;\n }\n }\n if ($dataLines === [] && $id === null && $retry === null) {\n return [null, null, $retry];\n }\n $data = implode(\"\\n\", $dataLines);\n $decoded = $jsonData && $data !== '' ? json_decode($data, true) : $data;\n return [new ServerSentEvent($event, $decoded, $id, $retry), $id, $retry];\n}\n\n/**\n * Stream server-sent events. `$open(array $extraHeaders): \\CurlHandle` returns a configured\n * (not yet executed) handle; this pump drives it with curl_multi, yields parsed frames, and\n * reconnects with `Last-Event-ID` on transient failures (4xx is definitive; backoff <= 30s).\n */\nfunction iterSse(callable $open, bool $jsonData): \\Generator\n{\n $lastEventId = null;\n $retryMs = 3000;\n while (true) {\n $extra = ['Accept' => 'text/event-stream'];\n if ($lastEventId !== null) {\n $extra['Last-Event-ID'] = $lastEventId;\n }\n $handle = $open($extra);\n $buffer = '';\n curl_setopt($handle, CURLOPT_WRITEFUNCTION, function ($ch, string $chunk) use (&$buffer): int {\n $buffer .= $chunk;\n return strlen($chunk);\n });\n $multi = curl_multi_init();\n curl_multi_add_handle($multi, $handle);\n do {\n curl_multi_exec($multi, $running);\n if ($running > 0) {\n curl_multi_select($multi, 0.1);\n }\n while (($split = strpos($buffer, \"\\n\\n\")) !== false || ($split = strpos($buffer, \"\\r\\n\\r\\n\")) !== false) {\n $frameLength = $buffer[$split] === \"\\r\" ? 4 : 2;\n $frame = substr($buffer, 0, $split);\n $buffer = substr($buffer, $split + $frameLength);\n [$event, $id, $retry] = parseSseFrame($frame, $jsonData);\n if ($id !== null) {\n $lastEventId = $id;\n }\n if ($retry !== null) {\n $retryMs = min($retry, 30000);\n }\n if ($event !== null) {\n yield $event;\n }\n }\n } while ($running > 0);\n $status = (int) curl_getinfo($handle, CURLINFO_RESPONSE_CODE);\n $url = (string) curl_getinfo($handle, CURLINFO_EFFECTIVE_URL);\n curl_multi_remove_handle($multi, $handle);\n curl_multi_close($multi);\n if ($status >= 400 && $status < 500) {\n throw new ApiError($url, $status, '', $buffer);\n }\n // A clean 200 end-of-stream is done; anything else reconnects with Last-Event-ID.\n if ($status === 200) {\n return;\n }\n usleep($retryMs * 1000);\n }\n}\n\n/** Encode an assoc body as `multipart/form-data`; nested values are JSON parts. Returns `[contentType, body]`. */\nfunction toMultipart(array $body): array\n{\n $boundary = 'redocly-' . bin2hex(random_bytes(12));\n $parts = '';\n foreach ($body as $name => $value) {\n $parts .= \"--{$boundary}\\r\\n\";\n if (is_array($value)) {\n $parts .= \"Content-Disposition: form-data; name=\\\"{$name}\\\"\\r\\n\";\n $parts .= \"Content-Type: application/json\\r\\n\\r\\n\";\n $parts .= json_encode($value) . \"\\r\\n\";\n } else {\n $parts .= \"Content-Disposition: form-data; name=\\\"{$name}\\\"\\r\\n\\r\\n\";\n $parts .= (is_bool($value) ? ($value ? 'true' : 'false') : (string) $value) . \"\\r\\n\";\n }\n }\n $parts .= \"--{$boundary}--\\r\\n\";\n return ['multipart/form-data; boundary=' . $boundary, $parts];\n}\n";
|
|
3
|
+
//# sourceMappingURL=php.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"php.js","sourceRoot":"","sources":["../../src/runtime-sources/php.ts"],"names":[],"mappings":"AAAA,iKAAiK;AACjK,MAAM,CAAC,MAAM,kBAAkB,GAC7B,g/kBAAg/kB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const PYTHON_RUNTIME_SOURCES: {
|
|
2
|
+
readonly '_errors.py': "# Runtime errors and the result-mode envelope for generated Python clients.\n# Hand-authored once, embedded into every generated client (see\n# scripts/generate-runtime-sources.mjs) — mirror of the TypeScript runtime's\n# errors.ts, kept semantically in lockstep.\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass\nfrom typing import Any, Generic, Optional, TypeVar\n\nT = TypeVar(\"T\")\nE = TypeVar(\"E\")\n\n\nclass ApiError(Exception):\n \"\"\"Raised (throw mode) for a non-2xx response, carrying the decoded error body.\"\"\"\n\n def __init__(self, url: str, status: int, status_text: str, body: Any) -> None:\n super().__init__(f\"Request failed with status {status}\")\n self.url = url\n self.status = status\n self.status_text = status_text\n self.body = body\n\n\nclass ApiTimeoutError(Exception):\n \"\"\"Raised when a request attempt exceeds the configured timeout — carries the\n context a log line needs (which operation, what budget, which attempt).\"\"\"\n\n def __init__(self, operation_id: str, timeout: float, attempt: int) -> None:\n super().__init__(\n f'Request \"{operation_id}\" timed out after {timeout} s (attempt {attempt})'\n )\n self.operation_id = operation_id\n self.timeout = timeout\n self.attempt = attempt\n\n\n@dataclass\nclass Result(Generic[T, E]):\n \"\"\"Result-mode return shape: exactly one of `data`/`error` is set.\"\"\"\n\n data: Optional[T]\n error: Optional[E]\n response: Any # httpx.Response\n\n @property\n def ok(self) -> bool:\n return self.error is None\n";
|
|
3
|
+
readonly '_auth.py': "# Auth resolution for generated Python clients — mirror of the TypeScript\n# runtime's auth.ts: the first OR-alternative whose schemes are all configured\n# is applied, so \"bearer OR apiKey\" works with either credential and never\n# sends both. Cookie-borne api keys fold into a single Cookie header.\nfrom __future__ import annotations\n\nimport base64\nfrom typing import Any, Callable, Dict, List, Tuple, Union\nfrom urllib.parse import quote\n\nTokenProvider = Union[str, Callable[[], str]]\n\n\ndef _api_keys(auth: Dict[str, Any]) -> Dict[str, Any]:\n \"\"\"The apiKey credentials. `apiKey` is the documented key (it matches the scheme\n kind and the other language SDKs); `api_key` is accepted too, so a snake_case\n config keeps working.\"\"\"\n return {**(auth.get(\"api_key\") or {}), **(auth.get(\"apiKey\") or {})}\n\ndef _resolve_token(provider: TokenProvider) -> str:\n return provider() if callable(provider) else provider\n\n\ndef _is_configured(scheme: Dict[str, Any], auth: Dict[str, Any]) -> bool:\n kind = scheme[\"kind\"]\n if kind == \"apiKey\":\n return scheme[\"scheme\"] in _api_keys(auth)\n if kind == \"bearer\":\n return auth.get(\"bearer\") is not None\n return auth.get(\"basic\") is not None\n\n\ndef resolve_auth(\n security: List[List[Dict[str, Any]]], auth: Dict[str, Any]\n) -> Tuple[Dict[str, str], Dict[str, str]]:\n \"\"\"Build (headers, query) for one operation's security OR-alternatives from\n the client credentials. When no alternative is fully configured, the first\n alternative's configured schemes are still sent (the server rejects the\n request — same behavior as the TypeScript runtime).\"\"\"\n alternative = next(\n (schemes for schemes in security if all(_is_configured(s, auth) for s in schemes)),\n security[0] if security else [],\n )\n headers: Dict[str, str] = {}\n query: Dict[str, str] = {}\n cookies: List[str] = []\n for scheme in alternative:\n kind = scheme[\"kind\"]\n if kind == \"apiKey\":\n provider = _api_keys(auth).get(scheme[\"scheme\"])\n if provider is None:\n continue\n value = _resolve_token(provider)\n location = scheme.get(\"in\", \"header\")\n if location == \"header\":\n headers[scheme[\"name\"]] = value\n elif location == \"query\":\n query[scheme[\"name\"]] = value\n else:\n # Reserved characters (`;`, `=`, space) must not break Cookie syntax.\n cookies.append(f\"{scheme['name']}={quote(value, safe='')}\")\n elif kind == \"bearer\":\n provider = auth.get(\"bearer\")\n if provider is not None:\n headers[\"Authorization\"] = f\"Bearer {_resolve_token(provider)}\"\n else:\n basic = auth.get(\"basic\")\n if basic is not None:\n username, password = basic[\"username\"], basic[\"password\"]\n token = base64.b64encode(f\"{username}:{password}\".encode(\"utf-8\")).decode(\"ascii\")\n headers[\"Authorization\"] = f\"Basic {token}\"\n if cookies:\n headers[\"Cookie\"] = \"; \".join(cookies)\n return headers, query\n";
|
|
4
|
+
readonly '_url.py': "# URL assembly for generated Python clients — path-parameter substitution with\n# percent-encoding, mirroring the TypeScript runtime's url.ts semantics.\nfrom __future__ import annotations\n\nfrom typing import Any, Dict\nfrom urllib.parse import quote\n\n\ndef build_url(server_url: str, path: str, path_params: Dict[str, Any]) -> str:\n filled = path\n for name, value in path_params.items():\n filled = filled.replace(\"{\" + name + \"}\", quote(str(value), safe=\"\"))\n return server_url.rstrip(\"/\") + filled\n";
|
|
5
|
+
readonly '_decode.py': "# Reflective JSON <-> model conversion for generated Python clients. Models are\n# plain dataclasses by default, or pydantic BaseModels under `models: pydantic`;\n# one decoder serves both. For a dataclass it hydrates parsed JSON reflectively,\n# honoring each class's `_field_map` (python name -> wire name) and the typing\n# constructs the generator emits: Optional/Union, List, Dict, Enum, Literal, Any.\n# For a pydantic model it defers to pydantic, which already knows the aliases.\n# encode() mirrors whichever it was given back to wire shape.\nfrom __future__ import annotations\n\nimport dataclasses\nimport typing\nfrom datetime import date, datetime\nfrom enum import Enum\nfrom typing import Any, Dict, Tuple, get_args, get_origin, get_type_hints\n\n# Discriminated unions: resolved Union annotation -> (wire property, {value: class}).\n# The generated module registers its unions here; decode() dispatches through it\n# before falling back to trying members in order.\nDISCRIMINATORS: Dict[Any, Tuple[str, Dict[str, Any]]] = {}\n\n\ndef decode(type_: Any, data: Any):\n \"\"\"Best-effort hydration: wire data -> the annotated Python shape. Unknown or\n mismatched shapes pass through unchanged (the server is the source of truth).\"\"\"\n if data is None or type_ is Any or type_ is None:\n return data\n # `Annotated[Union[...], Field(discriminator=...)]`: pydantic reads that annotation on a\n # model's own field, so here only the union underneath matters.\n if hasattr(type_, \"__metadata__\"):\n type_ = get_args(type_)[0]\n origin = get_origin(type_)\n if origin is typing.Union:\n discriminator = DISCRIMINATORS.get(type_)\n if discriminator is not None and isinstance(data, dict):\n wire_property, mapping = discriminator\n target = mapping.get(data.get(wire_property))\n if target is not None:\n try:\n return decode(target, data)\n except (TypeError, ValueError, KeyError):\n pass\n for member in get_args(type_):\n if member is type(None):\n continue\n try:\n return decode(member, data)\n except (TypeError, ValueError, KeyError):\n continue\n return data\n if origin is list:\n (item_type,) = get_args(type_) or (Any,)\n return [decode(item_type, item) for item in data]\n if origin is dict:\n args = get_args(type_)\n value_type = args[1] if len(args) == 2 else Any\n return {key: decode(value_type, value) for key, value in data.items()}\n if origin is typing.Literal:\n return data\n if isinstance(type_, type) and issubclass(type_, Enum):\n return type_(data)\n # `dateType: Date` annotates date/date-time fields as datetime objects; a value that\n # doesn't parse passes through unchanged (the server is the source of truth).\n if type_ is datetime or type_ is date:\n if not isinstance(data, str):\n return data\n try:\n # `datetime` accepts a bare date too; `date` rejects a timestamp, so trim it.\n return (\n datetime.fromisoformat(data)\n if type_ is datetime\n else date.fromisoformat(data[:10])\n )\n except ValueError:\n return data\n # A pydantic model validates itself, aliases included. `ValidationError`\n # subclasses `ValueError`, so union member probing above still works.\n if isinstance(type_, type) and hasattr(type_, \"model_validate\"):\n return type_.model_validate(data)\n if dataclasses.is_dataclass(type_):\n hints = get_type_hints(type_)\n field_map = getattr(type_, \"_field_map\", {})\n kwargs = {}\n for field in dataclasses.fields(type_):\n wire = field_map.get(field.name, field.name)\n if isinstance(data, dict) and wire in data:\n kwargs[field.name] = decode(hints.get(field.name, Any), data[wire])\n return type_(**kwargs)\n return data\n\n\ndef encode(value: Any):\n \"\"\"Python shape -> wire (JSON) shape; inverse of decode for request bodies.\"\"\"\n # `mode=\"json\"` resolves datetimes and enums the same way the branches below do,\n # and `exclude_none` matches the dataclass path: an unset optional is not sent.\n if hasattr(value, \"model_dump\") and not isinstance(value, type):\n return value.model_dump(by_alias=True, exclude_none=True, mode=\"json\")\n if dataclasses.is_dataclass(value) and not isinstance(value, type):\n field_map = getattr(type(value), \"_field_map\", {})\n out = {}\n for field in dataclasses.fields(value):\n item = getattr(value, field.name)\n if item is None:\n continue\n out[field_map.get(field.name, field.name)] = encode(item)\n return out\n if isinstance(value, Enum):\n return value.value\n # A date-only value must not gain a time component on the way out.\n if isinstance(value, datetime):\n return value.isoformat()\n if isinstance(value, date):\n return value.isoformat()\n if isinstance(value, list):\n return [encode(item) for item in value]\n if isinstance(value, dict):\n return {key: encode(item) for key, item in value.items()}\n return value\n";
|
|
6
|
+
readonly '_send.py': "# The request core for generated Python clients — mirror of the TypeScript\n# runtime's send.ts: default + config + per-call headers, on_request middleware\n# BEFORE serialization (mutations are sent), the retry loop (idempotent-methods\n# default, Idempotency-Key opt-in makes POST/PATCH safe, Retry-After honored,\n# exponential backoff with full jitter, a fresh timeout budget per attempt), and\n# the reverse on_response onion.\nfrom __future__ import annotations\n\nimport asyncio\nimport random\nimport time\nimport uuid\nfrom dataclasses import dataclass\nfrom typing import Any, Dict, Generic, List, Optional, Tuple, TypeVar\n\nimport httpx\n\nfrom ._errors import ApiTimeoutError\n\nT = TypeVar(\"T\")\n\n\n@dataclass\nclass Envelope(Generic[T]):\n \"\"\"A *_with_headers() result: decoded body + coerced declared headers + raw response.\"\"\"\n\n data: T\n headers: Dict[str, Any]\n response: httpx.Response\n\n\ndef read_envelope_headers(\n response: httpx.Response, specs: List[Tuple[str, str, str]]\n) -> Dict[str, Any]:\n \"\"\"Coerce declared response headers per (name, key, type) specs; absent/unparsable omitted.\"\"\"\n headers: Dict[str, Any] = {}\n for name, key, type_ in specs:\n raw = response.headers.get(name)\n if raw is None:\n continue\n if type_ in (\"integer\", \"number\"):\n try:\n headers[key] = int(raw) if type_ == \"integer\" else float(raw)\n except ValueError:\n pass\n elif type_ == \"boolean\":\n lower = raw.strip().lower()\n if lower in (\"true\", \"false\"):\n headers[key] = lower == \"true\"\n else:\n headers[key] = raw\n return headers\n\n\n_IDEMPOTENT_METHODS = {\"GET\", \"HEAD\", \"PUT\", \"DELETE\", \"OPTIONS\"}\n_TRANSIENT_STATUS = {408, 429, 500, 502, 503, 504}\n\n\ndef _default_retry_on(method: str, headers: Dict[str, str], response: Optional[httpx.Response]) -> bool:\n safe = method.upper() in _IDEMPOTENT_METHODS or \"Idempotency-Key\" in headers\n if not safe:\n return False\n return response is None or response.status_code in _TRANSIENT_STATUS\n\n\ndef _retry_delay(retry: Dict[str, Any], attempt: int, retry_after: Optional[str]) -> float:\n if retry_after:\n try:\n return float(retry_after)\n except ValueError:\n pass # HTTP-date form: fall through to backoff\n base = float(retry.get(\"retry_delay\", 1.0))\n raw = base if retry.get(\"retry_strategy\") == \"fixed\" else base * (2 ** (attempt - 1))\n return random.uniform(0, raw) if retry.get(\"jitter\", True) is not False else raw\n\n\ndef send(\n client: httpx.Client,\n config: Dict[str, Any],\n op: Dict[str, Any],\n url: str,\n *,\n method: str,\n headers: Optional[Dict[str, str]] = None,\n params: Optional[Dict[str, Any]] = None,\n json_body: Any = None,\n content: Any = None,\n data: Any = None,\n files: Any = None,\n timeout: Optional[float] = None,\n idempotency_key: Any = None,\n retry: Optional[Dict[str, Any]] = None,\n) -> httpx.Response:\n merged_retry: Dict[str, Any] = {**(config.get(\"retry\") or {}), **(retry or {})}\n effective_timeout = timeout if timeout is not None else config.get(\"timeout\")\n merged_headers: Dict[str, str] = {**(config.get(\"headers\") or {}), **(headers or {})}\n\n # One stable key per LOGICAL call — set before the retry loop so every\n # attempt re-sends the same key; a caller-provided header always wins.\n key = idempotency_key if idempotency_key is not None else config.get(\"idempotency_key\")\n if (\n key not in (None, False)\n and method.upper() in (\"POST\", \"PATCH\")\n and \"Idempotency-Key\" not in merged_headers\n ):\n merged_headers[\"Idempotency-Key\"] = (\n key if isinstance(key, str) else key() if callable(key) else str(uuid.uuid4())\n )\n\n context = {\n \"url\": url,\n \"method\": method.upper(),\n \"headers\": merged_headers,\n \"body\": json_body,\n \"operation\": op,\n }\n middleware: List[Any] = config.get(\"middleware\") or []\n for mw in middleware:\n on_request = getattr(mw, \"on_request\", None) or (mw.get(\"on_request\") if isinstance(mw, dict) else None)\n if on_request:\n on_request(context)\n\n max_attempts = 1 + int(merged_retry.get(\"retries\", 0))\n retry_on = merged_retry.get(\"retry_on\") or (\n lambda ctx: _default_retry_on(context[\"method\"], context[\"headers\"], ctx.get(\"response\"))\n )\n\n attempt = 0\n while True:\n attempt += 1\n try:\n response = client.request(\n context[\"method\"],\n context[\"url\"],\n headers=context[\"headers\"],\n params=params,\n json=context[\"body\"] if content is None and files is None and data is None else None,\n content=content,\n data=data,\n files=files,\n timeout=effective_timeout if effective_timeout is not None else httpx.USE_CLIENT_DEFAULT,\n )\n except httpx.TimeoutException:\n if attempt < max_attempts and retry_on({\"attempt\": attempt, \"response\": None}):\n time.sleep(_retry_delay(merged_retry, attempt, None))\n continue\n raise ApiTimeoutError(op.get(\"id\", \"?\"), float(effective_timeout or 0), attempt) from None\n except httpx.TransportError:\n if attempt < max_attempts and retry_on({\"attempt\": attempt, \"response\": None}):\n time.sleep(_retry_delay(merged_retry, attempt, None))\n continue\n raise\n\n for mw in reversed(middleware):\n on_response = getattr(mw, \"on_response\", None) or (mw.get(\"on_response\") if isinstance(mw, dict) else None)\n if on_response:\n replaced = on_response(response, context)\n if replaced is not None:\n response = replaced\n\n if (\n not response.is_success\n and attempt < max_attempts\n and retry_on({\"attempt\": attempt, \"response\": response})\n ):\n time.sleep(_retry_delay(merged_retry, attempt, response.headers.get(\"retry-after\")))\n continue\n return response\n\n\nasync def send_async(\n client: httpx.AsyncClient,\n config: Dict[str, Any],\n op: Dict[str, Any],\n url: str,\n *,\n method: str,\n headers: Optional[Dict[str, str]] = None,\n params: Optional[Dict[str, Any]] = None,\n json_body: Any = None,\n content: Any = None,\n data: Any = None,\n files: Any = None,\n timeout: Optional[float] = None,\n idempotency_key: Any = None,\n retry: Optional[Dict[str, Any]] = None,\n) -> httpx.Response:\n \"\"\"The async mirror of send() — same retry/timeout/idempotency semantics.\"\"\"\n merged_retry: Dict[str, Any] = {**(config.get(\"retry\") or {}), **(retry or {})}\n effective_timeout = timeout if timeout is not None else config.get(\"timeout\")\n merged_headers: Dict[str, str] = {**(config.get(\"headers\") or {}), **(headers or {})}\n key = idempotency_key if idempotency_key is not None else config.get(\"idempotency_key\")\n if (\n key not in (None, False)\n and method.upper() in (\"POST\", \"PATCH\")\n and \"Idempotency-Key\" not in merged_headers\n ):\n merged_headers[\"Idempotency-Key\"] = (\n key if isinstance(key, str) else key() if callable(key) else str(uuid.uuid4())\n )\n context = {\n \"url\": url,\n \"method\": method.upper(),\n \"headers\": merged_headers,\n \"body\": json_body,\n \"operation\": op,\n }\n middleware: List[Any] = config.get(\"middleware\") or []\n for mw in middleware:\n on_request = getattr(mw, \"on_request\", None) or (mw.get(\"on_request\") if isinstance(mw, dict) else None)\n if on_request:\n on_request(context)\n max_attempts = 1 + int(merged_retry.get(\"retries\", 0))\n retry_on = merged_retry.get(\"retry_on\") or (\n lambda ctx: _default_retry_on(context[\"method\"], context[\"headers\"], ctx.get(\"response\"))\n )\n attempt = 0\n while True:\n attempt += 1\n try:\n response = await client.request(\n context[\"method\"],\n context[\"url\"],\n headers=context[\"headers\"],\n params=params,\n json=context[\"body\"] if content is None and files is None and data is None else None,\n content=content,\n data=data,\n files=files,\n timeout=effective_timeout if effective_timeout is not None else httpx.USE_CLIENT_DEFAULT,\n )\n except httpx.TimeoutException:\n if attempt < max_attempts and retry_on({\"attempt\": attempt, \"response\": None}):\n await asyncio.sleep(_retry_delay(merged_retry, attempt, None))\n continue\n raise ApiTimeoutError(op.get(\"id\", \"?\"), float(effective_timeout or 0), attempt) from None\n except httpx.TransportError:\n if attempt < max_attempts and retry_on({\"attempt\": attempt, \"response\": None}):\n await asyncio.sleep(_retry_delay(merged_retry, attempt, None))\n continue\n raise\n for mw in reversed(middleware):\n on_response = getattr(mw, \"on_response\", None) or (mw.get(\"on_response\") if isinstance(mw, dict) else None)\n if on_response:\n replaced = on_response(response, context)\n if replaced is not None:\n response = replaced\n if (\n not response.is_success\n and attempt < max_attempts\n and retry_on({\"attempt\": attempt, \"response\": response})\n ):\n await asyncio.sleep(_retry_delay(merged_retry, attempt, response.headers.get(\"retry-after\")))\n continue\n return response\n";
|
|
7
|
+
readonly '_paginate.py': "# Auto-pagination iterators for generated Python clients — the TypeScript\n# runtime's paginate.ts semantics ported: cursor (next-cursor pointer, optional\n# has-more flag, repeated-cursor guard), offset/page (advance by count/one,\n# repeated-page guard, null start treated as absent), and link (RFC 8288\n# `Link: rel=\"next\"` following with relative resolution and a loop guard).\nfrom __future__ import annotations\n\nimport re\nfrom typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, Optional, Tuple\nfrom urllib.parse import parse_qsl, urljoin, urlparse\n\n# call(params) -> (parsed_json, httpx.Response)\nPageCall = Callable[[Dict[str, Any]], Tuple[Any, Any]]\n\n\ndef resolve_pointer(data: Any, pointer: str) -> Any:\n \"\"\"RFC 6901 JSON pointer over parsed JSON; None on any miss.\"\"\"\n if pointer == \"\":\n return data\n if not pointer.startswith(\"/\"):\n return None\n current = data\n for token in pointer[1:].split(\"/\"):\n key = token.replace(\"~1\", \"/\").replace(\"~0\", \"~\")\n if isinstance(current, dict):\n current = current.get(key)\n elif isinstance(current, list) and key.isdigit():\n index = int(key)\n current = current[index] if index < len(current) else None\n else:\n return None\n if current is None:\n return None\n return current\n\n\ndef iter_pages(call: PageCall, spec: Dict[str, Any], params: Optional[Dict[str, Any]] = None) -> Iterator[Any]:\n \"\"\"Yield raw page JSON per the pagination spec; every page is yielded before\n the stop condition is evaluated, so the last page always arrives.\"\"\"\n style = spec[\"style\"]\n base = dict(params or {})\n if style == \"cursor\":\n cursor = base.get(spec[\"param\"])\n while True:\n page_params = dict(base)\n if cursor is not None:\n page_params[spec[\"param\"]] = cursor\n page, _response = call(page_params)\n yield page\n if spec.get(\"has_more\") is not None and resolve_pointer(page, spec[\"has_more\"]) is False:\n return\n nxt = resolve_pointer(page, spec.get(\"next_cursor\", \"\"))\n if nxt is None or nxt == \"\":\n return\n if not isinstance(nxt, (str, int, float)):\n raise ValueError(f\"Pagination cursor at {spec['next_cursor']} is not a string or number\")\n if nxt == cursor:\n raise ValueError(\"Pagination did not advance: the operation returned the same cursor twice\")\n cursor = nxt\n elif style == \"link\":\n yield from _iter_pages_by_link(call, base)\n else: # offset / page\n start = base.get(spec[\"param\"])\n fallback = 1 if style == \"page\" else 0\n try:\n position = fallback if start in (None, \"\") else int(start)\n except (TypeError, ValueError):\n position = fallback\n previous_items = None\n while True:\n page, _response = call({**base, spec[\"param\"]: position})\n items = resolve_pointer(page, spec.get(\"items\", \"\"))\n serialized = repr(items) if isinstance(items, list) else None\n if serialized is not None and serialized == previous_items:\n raise ValueError(\"Pagination did not advance: the operation returned the same page twice\")\n yield page\n if not isinstance(items, list) or len(items) == 0:\n return\n previous_items = serialized\n position += 1 if style == \"page\" else len(items)\n\n\ndef _link_next(header: Optional[str]) -> Optional[str]:\n if not header:\n return None\n for entry in re.split(r\",\\s*(?=<)\", header):\n match = re.match(r\"^\\s*<([^>]*)>(.*)$\", entry)\n if not match:\n continue\n rel = re.search(r';\\s*rel\\s*=\\s*\"?([^\";]+)\"?', match.group(2), re.IGNORECASE)\n if rel and \"next\" in rel.group(1).split():\n return match.group(1)\n return None\n\n\ndef _iter_pages_by_link(call: PageCall, base: Dict[str, Any]) -> Iterator[Any]:\n params = dict(base)\n previous = None\n while True:\n page, response = call(params)\n yield page\n target = _link_next(response.headers.get(\"link\"))\n if target is None:\n return\n page_url = str(response.request.url) if response.request is not None else \"\"\n nxt = urljoin(page_url or \"http://relative.invalid\", target)\n if nxt in (previous, page_url):\n raise ValueError('Pagination did not advance: the Link rel=\"next\" target repeats')\n previous = nxt\n link_params: Dict[str, Any] = {}\n for key, value in parse_qsl(urlparse(nxt).query):\n if key in link_params:\n existing = link_params[key]\n link_params[key] = [*existing, value] if isinstance(existing, list) else [existing, value]\n else:\n link_params[key] = value\n params = {**base, **link_params}\n\n\ndef iter_items(call: PageCall, spec: Dict[str, Any], params: Optional[Dict[str, Any]] = None) -> Iterator[Any]:\n \"\"\"Each page's `items` pointer, flattened.\"\"\"\n for page in iter_pages(call, spec, params):\n items = resolve_pointer(page, spec.get(\"items\", \"\"))\n if isinstance(items, list):\n yield from items\n\n\n# call(params) -> awaitable of (parsed_json, httpx.Response)\nAsyncPageCall = Callable[[Dict[str, Any]], Awaitable[Tuple[Any, Any]]]\n\n\nasync def aiter_pages(\n call: AsyncPageCall, spec: Dict[str, Any], params: Optional[Dict[str, Any]] = None\n) -> AsyncIterator[Any]:\n \"\"\"Async mirror of iter_pages — same stop conditions and guards.\"\"\"\n style = spec[\"style\"]\n base = dict(params or {})\n if style == \"cursor\":\n cursor = base.get(spec[\"param\"])\n while True:\n page_params = dict(base)\n if cursor is not None:\n page_params[spec[\"param\"]] = cursor\n page, _response = await call(page_params)\n yield page\n if spec.get(\"has_more\") is not None and resolve_pointer(page, spec[\"has_more\"]) is False:\n return\n nxt = resolve_pointer(page, spec.get(\"next_cursor\", \"\"))\n if nxt is None or nxt == \"\":\n return\n if not isinstance(nxt, (str, int, float)):\n raise ValueError(f\"Pagination cursor at {spec['next_cursor']} is not a string or number\")\n if nxt == cursor:\n raise ValueError(\"Pagination did not advance: the operation returned the same cursor twice\")\n cursor = nxt\n elif style == \"link\":\n previous = None\n link_params: Dict[str, Any] = dict(base)\n while True:\n page, response = await call(link_params)\n yield page\n target = _link_next(response.headers.get(\"link\"))\n if target is None:\n return\n page_url = str(response.request.url) if response.request is not None else \"\"\n nxt = urljoin(page_url or \"http://relative.invalid\", target)\n if nxt in (previous, page_url):\n raise ValueError('Pagination did not advance: the Link rel=\"next\" target repeats')\n previous = nxt\n merged: Dict[str, Any] = {}\n for key, value in parse_qsl(urlparse(nxt).query):\n if key in merged:\n existing = merged[key]\n merged[key] = [*existing, value] if isinstance(existing, list) else [existing, value]\n else:\n merged[key] = value\n link_params = {**base, **merged}\n else:\n start = base.get(spec[\"param\"])\n fallback = 1 if style == \"page\" else 0\n try:\n position = fallback if start in (None, \"\") else int(start)\n except (TypeError, ValueError):\n position = fallback\n previous_items = None\n while True:\n page, _response = await call({**base, spec[\"param\"]: position})\n items = resolve_pointer(page, spec.get(\"items\", \"\"))\n serialized = repr(items) if isinstance(items, list) else None\n if serialized is not None and serialized == previous_items:\n raise ValueError(\"Pagination did not advance: the operation returned the same page twice\")\n yield page\n if not isinstance(items, list) or len(items) == 0:\n return\n previous_items = serialized\n position += 1 if style == \"page\" else len(items)\n\n\nasync def aiter_items(\n call: AsyncPageCall, spec: Dict[str, Any], params: Optional[Dict[str, Any]] = None\n) -> AsyncIterator[Any]:\n async for page in aiter_pages(call, spec, params):\n items = resolve_pointer(page, spec.get(\"items\", \"\"))\n if isinstance(items, list):\n for item in items:\n yield item\n";
|
|
8
|
+
readonly '_sse.py': "# Server-Sent Events for generated Python clients — the TypeScript runtime's\n# sse.ts semantics ported: frame parsing per the EventSource spec (retry must be\n# ASCII digits; comment-only frames skipped; multi-line data joined with \\n) and\n# auto-reconnect resuming from the last event id via Last-Event-ID, with\n# exponential backoff capped at 30s. JSON payloads are parsed when the operation\n# declares a JSON event stream.\nfrom __future__ import annotations\n\nimport asyncio\nimport json\nimport random\nimport time\nfrom dataclasses import dataclass\nfrom typing import Any, AsyncIterator, Callable, Dict, Iterator, Optional\n\nimport httpx\n\n_FRAME_DELIMITER = \"\\n\\n\"\n\n\n@dataclass\nclass ServerSentEvent:\n data: Any\n event: Optional[str] = None\n id: Optional[str] = None\n retry: Optional[int] = None\n\n\ndef parse_sse_frame(raw: str, data_kind: str = \"text\") -> Optional[ServerSentEvent]:\n event = None\n data_lines = []\n event_id = None\n retry = None\n saw_field = False\n for line in raw.replace(\"\\r\\n\", \"\\n\").replace(\"\\r\", \"\\n\").split(\"\\n\"):\n if line == \"\" or line.startswith(\":\"):\n continue\n field, _, value = line.partition(\":\")\n if value.startswith(\" \"):\n value = value[1:]\n saw_field = True\n if field == \"event\":\n event = value\n elif field == \"data\":\n data_lines.append(value)\n elif field == \"id\":\n event_id = value\n elif field == \"retry\" and value.isdigit():\n retry = int(value)\n if not saw_field:\n return None\n text = \"\\n\".join(data_lines)\n data: Any = text\n if data_kind == \"json\" and text != \"\":\n data = json.loads(text)\n return ServerSentEvent(data=data, event=event, id=event_id, retry=retry)\n\n\ndef iter_sse(\n open_stream: Callable[[Dict[str, str]], Any],\n data_kind: str = \"text\",\n reconnect: bool = True,\n reconnect_delay: float = 1.0,\n) -> Iterator[ServerSentEvent]:\n \"\"\"Iterate an event stream. `open_stream(extra_headers)` must return an\n httpx streaming-response context manager; it is reopened on dropped\n connections with Last-Event-ID set (fresh call = fresh auth).\"\"\"\n last_event_id: Optional[str] = None\n server_retry: Optional[float] = None\n failures = 0\n while True:\n headers = {\"Accept\": \"text/event-stream\"}\n if last_event_id is not None:\n headers[\"Last-Event-ID\"] = last_event_id\n try:\n with open_stream(headers) as response:\n if response.status_code >= 400:\n response.read()\n raise httpx.HTTPStatusError(\n f\"SSE request failed with status {response.status_code}\",\n request=response.request,\n response=response,\n )\n failures = 0\n buffer = \"\"\n for chunk in response.iter_text():\n buffer += chunk\n while _FRAME_DELIMITER in buffer:\n raw, buffer = buffer.split(_FRAME_DELIMITER, 1)\n parsed = parse_sse_frame(raw, data_kind)\n if parsed is not None:\n if parsed.id is not None:\n last_event_id = parsed.id\n if parsed.retry is not None:\n server_retry = parsed.retry / 1000\n yield parsed\n # Clean end: flush a trailing frame, then finish (no reconnect).\n if buffer.strip():\n parsed = parse_sse_frame(buffer, data_kind)\n if parsed is not None:\n yield parsed\n return\n except httpx.HTTPStatusError:\n raise # a 4xx/5xx is definitive, not a dropped connection\n except (httpx.TransportError, httpx.TimeoutException):\n if not reconnect:\n raise\n failures += 1\n base = server_retry if server_retry is not None else reconnect_delay\n time.sleep(random.uniform(0, min(base * (2 ** (failures - 1)), 30.0)))\n\n\nasync def aiter_sse(\n open_stream: Callable[[Dict[str, str]], Any],\n data_kind: str = \"text\",\n reconnect: bool = True,\n reconnect_delay: float = 1.0,\n) -> AsyncIterator[ServerSentEvent]:\n \"\"\"Async mirror of iter_sse; `open_stream` returns an async context manager.\"\"\"\n last_event_id: Optional[str] = None\n server_retry: Optional[float] = None\n failures = 0\n while True:\n headers = {\"Accept\": \"text/event-stream\"}\n if last_event_id is not None:\n headers[\"Last-Event-ID\"] = last_event_id\n try:\n async with open_stream(headers) as response:\n if response.status_code >= 400:\n await response.aread()\n raise httpx.HTTPStatusError(\n f\"SSE request failed with status {response.status_code}\",\n request=response.request,\n response=response,\n )\n failures = 0\n buffer = \"\"\n async for chunk in response.aiter_text():\n buffer += chunk\n while _FRAME_DELIMITER in buffer:\n raw, buffer = buffer.split(_FRAME_DELIMITER, 1)\n parsed = parse_sse_frame(raw, data_kind)\n if parsed is not None:\n if parsed.id is not None:\n last_event_id = parsed.id\n if parsed.retry is not None:\n server_retry = parsed.retry / 1000\n yield parsed\n if buffer.strip():\n parsed = parse_sse_frame(buffer, data_kind)\n if parsed is not None:\n yield parsed\n return\n except httpx.HTTPStatusError:\n raise\n except (httpx.TransportError, httpx.TimeoutException):\n if not reconnect:\n raise\n failures += 1\n base = server_retry if server_retry is not None else reconnect_delay\n await asyncio.sleep(random.uniform(0, min(base * (2 ** (failures - 1)), 30.0)))\n";
|
|
9
|
+
readonly '_multipart.py': "# Multipart bodies for generated Python clients — a typed dict/dataclass body is\n# split into httpx's (data, files): bytes and file-like values upload as parts,\n# everything else is form data (nested values JSON-encoded, mirroring the\n# TypeScript runtime's FormData serialization).\nfrom __future__ import annotations\n\nimport json\nfrom typing import Any, Dict, Tuple\n\nfrom ._decode import encode\n\n\ndef to_multipart(body: Any) -> Tuple[Dict[str, Any], Dict[str, Any]]:\n wire = encode(body)\n data: Dict[str, Any] = {}\n files: Dict[str, Any] = {}\n for key, value in (wire or {}).items():\n if isinstance(value, (bytes, bytearray)) or hasattr(value, \"read\"):\n files[key] = value\n elif isinstance(value, (dict, list)):\n data[key] = json.dumps(value)\n else:\n data[key] = value\n return data, files\n";
|
|
10
|
+
};
|
|
11
|
+
export type PythonRuntimeModuleName = keyof typeof PYTHON_RUNTIME_SOURCES;
|
|
12
|
+
//# sourceMappingURL=python.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python.d.ts","sourceRoot":"","sources":["../../src/runtime-sources/python.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,sBAAsB;;;;;;;;;CAiBzB,CAAC;AAEX,MAAM,MAAM,uBAAuB,GAAG,MAAM,OAAO,sBAAsB,CAAC"}
|