Skip to content

fix(typescript): match SDK request/auth shape in dynamic snippets - #17746

Merged
dvdaruri-art merged 18 commits into
mainfrom
devin/1789483869-ts-dynamic-snippets-flatten-body-auth-wrapper
Sep 16, 2026
Merged

dvdaruri-art merged 18 commits into
mainfrom
devin/1789483869-ts-dynamic-snippets-flatten-body-auth-wrapper

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Description

Refs Pylon issue 23380 (Payabli): TypeScript API-reference code samples don't match the generated TypeScript SDK.

Two independent mismatches between the TS dynamic snippet generator and the TS SDK generator:

  1. flattenRequestParameters — the SDK spreads a referenced request body's properties into the request wrapper when the body resolves to a named object type (GeneratedRequestWrapperImpl.getFlattenedReferencedRequestBodyProperties), but snippets always emitted body: { ... }.
    -await client.params.postBodyAndQuery({ body: { string: "value" } });
    +await client.params.postBodyAndQuery({ string: "value" });
  2. Multi-auth constructor options — with auth.requirement of ANY or ENDPOINT_SECURITY the SDK nests each scheme's constructor options under a camelCased scheme-key property (SdkGenerator.shouldUseWrapper), but snippets emitted them flat.
    -new Client({ clientId: "...", clientSecret: "..." })
    +new Client({ oauth: { clientId: "...", clientSecret: "..." } })

Note on scope of the flatten fix: the path/body collision only exists when the path parameter is declared inside the endpoint's request: block (inlined request). An endpoint-level path-parameters: with a directly referenced body is emitted positionally by both the SDK and the snippet generator (updateUserProfile("user-1", { ... })), so nothing changes there. The new ts-flatten-request-any-auth fixture pins both shapes.

Changes Made

  • Dynamic IR (67.25.0 → 67.27.0; main took 67.26.0 for baseUrlEnvVar while this was open): new dynamic.BaseAuth { wrapperProperty: optional<Name> } extended by BasicAuth/BearerAuth/HeaderAuth/OAuth/InferredAuth; regenerated packages/ir-sdk/src/sdk, dated changelog entry. Kept language-neutral (a Name, not a TS-specific flag).
  • CLI DynamicSnippetsConverter.convertAuth: new getAuthWrapperProperty(auth, scheme) (exhaustive switch on auth.requirement + assertNever) returns generateName(scheme.key) for ANY/ENDPOINT_SECURITY, undefined for ALL. Dynamic test-definition JSONs regenerated (wrapperProperty: null/set).
  • TS dynamic snippets EndpointSnippetGenerator:
    • referenced body + customConfig.flattenRequestParameters === true + body type resolves to an object → emit the object's fields directly (via TypeLiteral.getObjectFields(), new accessor in typescript-v2/ast). Non-object bodies (bytes, primitives, aliases, optional<...>) and default config are unchanged — same rule as the SDK.
    • Path-parameter fields whose name collides with a request-body field are dropped from the inlined request object (the SDK omits them too — getCollidingPathParameterPropertyNames).
    • Each getConstructor*AuthArgs goes through wrapAuthFields, which nests fields under wrapperProperty when present. The wrapper key is always camelCase(scheme.key) (with the SDK's OAuth → oauth special case), not context.getPropertyName(...) — under noSerdeLayer/retainOriginalCasing that would emit the original scheme name (BearerAuth: {...}), which the SDK rejects (*AuthProviderGenerator.getWrapperPropertyName uses toCamelCase unconditionally).
    • This package pins the published @fern-api/dynamic-ir-sdk@67.21.0, which doesn't have the field yet, so it reads wrapperProperty through a named type guard (hasWrapperPropertyField, marked TODO). Serialized fixtures always carry wrapperProperty: null, so the guard is about the field existing; getAuthWrapperProperty maps null → undefined. Follow-up once the new IR is published: bump the dep and delete the guard.
  • New fixture test-definitions/fern/apis/ts-flatten-request-any-auth (ts-prefixed → seed runs it for ts-sdk only): auth: any: [BearerAuth, ApiKey]; PUT /users/{id} with the path param declared in the request: block and a referenced UpdateUser { id, name } body (deliberate id collision); PUT /users/{id}/profile with an endpoint-level path param. Seed output committed under seed/ts-sdk/ts-flatten-request-any-auth/{no-custom-config,flatten-request-parameters} — the generated SDK is the ground truth the snippet tests assert against (UpdateUserRequest { id; name }, AuthOptions = { bearerAuth?: { token? } }, positional updateUserProfile(id, request)).
    • The fixture examples use the same value (user-1) for the path id and body id. With the collision the generated SDK necessarily sends the body's id in the URL, but the TS wire-test generator mocks the URL from the example's path-parameter value — with differing values the wire test can't pass. That wire-test-generator gap is pre-existing and out of scope; the snippet unit tests still use distinct path-id/body-id values (they don't read example values) so precedence is still asserted.
  • Changelogs: packages/cli/cli/changes/unreleased/dynamic-auth-wrapper-property.yml, generators/typescript/sdk/changes/unreleased/dynamic-snippets-flatten-body-and-auth-wrapper.yml.
  • Updated README.md generator (not applicable)

Testing

  • Unit tests added/updated
    • generators/typescript-v2/dynamic-snippets/src/__test__/FlattenRequestParameters.test.ts — modified-exhaustive cases (flatten on / default / non-object body / path-param collision) plus unmodified real-fixture cases: flatten on → id: "body-id", name: "Ada", no body:, no "path-id", exactly one id:; flatten off → id: "path-id" + body: {; endpoint-level path param → updateUserProfile("path-id", {.
    • generators/typescript-v2/dynamic-snippets/src/__test__/AuthWrapperProperty.test.ts — nested vs flat, the real fixture → bearerAuth: { token: "<token>" }, the same fixture under noSerdeLayer: true and retainOriginalCasing: true → still bearerAuth (never BearerAuth), and OAuth via java-endpoint-security-token-subpackage under noSerdeLayeroauth: { clientId, clientSecret }.
    • packages/cli/generation/ir-generator-tests/src/dynamic-snippets/__test__/authWrapperPropertyDynamic.test.ts — single scheme → unset; it.each over any-auth (ANY) and endpoint-security-auth (ENDPOINT_SECURITY) → Bearer/bearer; real fixture → BearerAuth/bearerAuth and asserts the IR shape the collision logic relies on (inlined request, referenced body, path param id).
    • The real-fixture tests consume the converter-produced ts-flatten-request-any-auth.json as-is, so CLI converter → TS generator run together.
  • Local: pnpm ir:generate + @fern-api/ir-sdk compile; turbo compile for ir-generator, ir-generator-tests, typescript-dynamic-snippets; TS dynamic-snippets suite 50/50; CLI dynamic-snippets suite 253/253; snapshot regeneration 543 passed; seed ts-sdk for the new fixture (2/2, validator passed); Biome format/lint clean.
  • Manual testing completed — end-to-end Fern definition → CLI IR → dynamic IR → TS snippet on main vs this branch for the fixture above; main emits new AcmeClient({ token }) + { id: "path-id", body: {...} }, this branch emits new AcmeClient({ bearerAuth: { token } }) + { id: "body-id", name: "Ada" }.
  • Manual testing against Payabli's real OpenAPI project (268 endpoints; endpoint-security with BearerAuth OAuth client-credentials + APIKeyAuth; flattenRequestParameters: true, noSerdeLayer: true, inlinePathParameters: false) on main vs this branch, with their TS SDK generated via seed from the same spec as ground truth: POST /v2/MoneyIn/getpaid goes from getpaidv2({ body: {...} }) to getpaidv2({ paymentDetails, paymentMethod, ... }) (matches RequestPaymentV2), and the constructor goes from { clientId, clientSecret } to { bearerAuth: { clientId, clientSecret } } (matches OAuthAuthProvider.ClientCredentials = { bearerAuth?: {...} }). Positional path-param endpoints (PUT /Customer/{customerId}, PUT /Subscription/{subId}) are unchanged. The only diff across all 268 endpoints is the auth nesting.

Link to Devin session: https://app.devin.ai/sessions/0d0077731be1453cbf57f84b5f9ba2ec
Open in Devin Desktop: https://app.devin.ai/desktop/session/0d0077731be1453cbf57f84b5f9ba2ec?variant=devin


Devin Review

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@nitpickybot nitpickybot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Review Summary

Adds a wrapperProperty to dynamic-IR auth schemes (multi-auth nesting) and teaches the TS dynamic-snippet generator to flatten referenced request bodies under flattenRequestParameters. Implementation broadly mirrors the SDK generators; the main risks I see are the flattening path not handling optional/nullable body wrappers and the temporary structural type guard for wrapperProperty silently degrading if the field is ever renamed.

  • 🟡 1 warning(s)
  • 🔵 4 suggestion(s)

This review is complete for the current scope. Addressing all critical and warning findings above satisfies the review; suggestions are optional. Request another review only if subsequent changes introduce new behavior or materially expand the pull request's scope.

Comment on lines +698 to +703
const flattened = this.context.dynamicTypeLiteralMapper.convert({
typeReference: body.bodyType.value,
value,
convertOpts: { isForRequest: true }
});
const fields = flattened.getObjectFields();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 suggestion

dynamicTypeLiteralMapper.convert is called here and then again inside getReferencedRequestBodyPropertyObjectField when fields == null. Any errors the mapper records into the context (e.g. type mismatches on the request body) will therefore be reported twice in that fallback path. Worth caching the converted literal and reusing it instead of converting twice.

Comment on lines +27 to +33
function hasAuthWrapperProperty(auth: AuthFields): auth is AuthWithWrapperProperty {
return "wrapperProperty" in auth;
}

function getAuthWrapperProperty(auth: AuthFields): FernIr.dynamic.Name | undefined {
return hasAuthWrapperProperty(auth) ? auth.wrapperProperty : undefined;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 suggestion

hasAuthWrapperProperty is a structural "wrapperProperty" in auth check against a pinned older dynamic-ir-sdk. If the IR field is ever renamed this degrades silently to "no wrapper" rather than failing to compile. Since the PR description already plans a follow-up dep bump, please leave a // TODO(<owner>): remove once @fern-api/dynamic-ir-sdk >= 67.26.0 comment here (and in the mirrored guard in authWrapperPropertyDynamic.test.ts) so the temporary shim doesn't outlive its purpose.

const response = await generator.generate(REQUEST);

expect(response.snippet).toContain("token:");
expect(response.snippet).not.toContain("bearerAuth");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 suggestion

not.toContain("bearerAuth") is a fairly loose assertion — it would also pass (or fail) for unrelated occurrences of that substring elsewhere in the snippet. Asserting on the exact expected constructor snippet (or at least not.toContain("bearerAuth: {")) makes the intent clearer and less brittle.

Comment on lines +14 to +16
modifyIr?: (
ir: import("@fern-api/dynamic-ir-sdk").FernIr.dynamic.DynamicIntermediateRepresentation
) => import("@fern-api/dynamic-ir-sdk").FernIr.dynamic.DynamicIntermediateRepresentation;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 suggestion

Inline import(...) type references are unusual here given the file already imports from @fern-api/dynamic-ir-sdk-adjacent modules. A top-level import type { FernIr } from "@fern-api/dynamic-ir-sdk"; and modifyIr?: (ir: FernIr.dynamic.DynamicIntermediateRepresentation) => FernIr.dynamic.DynamicIntermediateRepresentation; would read better.

Suggested change
modifyIr?: (
ir: import("@fern-api/dynamic-ir-sdk").FernIr.dynamic.DynamicIntermediateRepresentation
) => import("@fern-api/dynamic-ir-sdk").FernIr.dynamic.DynamicIntermediateRepresentation;
modifyIr?: (
ir: FernIr.dynamic.DynamicIntermediateRepresentation
) => FernIr.dynamic.DynamicIntermediateRepresentation;

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

Devin Review

Comment on lines +758 to +760
const wrapperProperty =
auth.requirement === "ANY" || auth.requirement === "ENDPOINT_SECURITY"
? this.fullCasingsGenerator.generateName(scheme.key)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Endpoint-specific auth uses wrong scheme

When an ENDPOINT_SECURITY endpoint excludes the first global scheme, wrapperProperty still selects that scheme. convertEndpoint assigns this auth to every endpoint, producing unusable credentials.

Learn more

Endpoint security lets each endpoint select a subset or combination of the API's global auth schemes. The converter selects auth.schemes[0] once, builds one dynamic auth object, and assigns it to every endpoint in convertEndpoint. The new wrapper therefore preserves the same globally selected scheme even when an endpoint routes through another provider. A generated snippet can construct the client successfully but omit the credential required for that endpoint.

Example: An API declares Bearer first and ApiKey second. An endpoint permits only ApiKey. Its dynamic snippet still emits { bearer: { token: "..." } }, so the SDK's ApiKey route has no credential.

Recommended fix: Derive each endpoint's dynamic auth and example auth values from that endpoint's security requirements. Preserve the selected scheme key in wrapperProperty, and define deterministic handling for endpoint requirements containing multiple alternatives or combined schemes.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pre-existing: the converter has always picked auth.schemes[0] once and attached it to every endpoint; this PR only adds the wrapper name for that same scheme, so it doesn't regress anything. Deriving per-endpoint auth from endpoint security requirements is a larger change to the dynamic IR (Endpoint.auth would need to be per-endpoint-resolved) and is out of scope here — happy to file it as a follow-up.

Comment thread generators/typescript-v2/dynamic-snippets/src/EndpointSnippetGenerator.ts Outdated
dvdaruri-art and others added 2 commits September 15, 2026 15:23
…elds in snippets

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@github-actions

github-actions Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Docs Generation Benchmark Results

Comparing PR branch against median of 5 nightly run(s) on main (latest: 2026-09-16T04:06:27Z).

Fixture main PR Delta
docs 268.5s (n=5) 274.6s (35 versions) +6.1s (+2.3%)

Docs generation runs fern generate --docs --preview end-to-end against the benchmark fixture with 35 API versions (each version: markdown processing + OpenAPI-to-IR + FDR upload).
Delta is computed against the nightly baseline on main.
Baseline from nightly run(s) on main (latest: 2026-09-16T04:06:27Z). Trigger benchmark-baseline to refresh.
Last updated: 2026-09-16 19:05 UTC

@github-actions

github-actions Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

SDK Generation Benchmark Results

Comparing PR branch against median of 5 nightly run(s) on main (latest: 2026-09-16T04:06:27Z).

Full benchmark table (click to expand)
Generator Spec main (generator) main (E2E) PR (generator) Delta
csharp-sdk square 95s (n=5) 113s (n=5) 94s -1s (-1.1%)
go-sdk square 134s (n=5) 295s (n=5) 103s -31s (-23.1%)
java-sdk square 221s (n=5) 272s (n=5) 218s -3s (-1.4%)
php-sdk square 78s (n=5) N/A 74s -4s (-5.1%)
python-sdk square 157s (n=5) 252s (n=5) 159s +2s (+1.3%)
ruby-sdk-v2 square 102s (n=5) 148s (n=5) 83s -19s (-18.6%)
rust-sdk square 181s (n=5) 208s (n=5) 200s +19s (+10.5%)
swift-sdk square 58s (n=5) 435s (n=5) 78s +20s (+34.5%)
ts-sdk square 170s (n=5) 167s (n=5) 123s -47s (-27.6%)

main (generator): generator-only time via --skip-scripts (includes Docker image build, container startup, IR parsing, and code generation — this is the same Docker-based flow customers use via fern generate). main (E2E): full customer-observable time including build/test scripts (nightly baseline, informational). Delta is computed against generator-only baseline.
⚠️ = generation exited with a non-zero exit code (timing may not reflect a successful run).
Baseline from nightly runs on main (latest: 2026-09-16T04:06:27Z). Trigger benchmark-baseline to refresh.
Last updated: 2026-09-16 19:06 UTC

dvdaruri-art and others added 13 commits September 15, 2026 20:52
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ody-auth-wrapper

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… of serde config

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@dvdaruri-art
dvdaruri-art merged commit 6387cf4 into main Sep 16, 2026
233 checks passed
@dvdaruri-art
dvdaruri-art deleted the devin/1789483869-ts-dynamic-snippets-flatten-body-auth-wrapper branch September 16, 2026 20:26
devin-ai-integration Bot added a commit that referenced this pull request Sep 16, 2026
…7746)

* fix(typescript): match SDK request/auth shape in dynamic snippets

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore(typescript): address review nits on dynamic snippet auth/flatten

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(typescript): drop path params that collide with flattened body fields in snippets

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(cli): update auth wrapperProperty snapshots

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(cli): add TypeScript flattening fixture snapshots

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(ts-sdk): add flattening seed fixture output

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(typescript): cover real fixture dynamic snippets

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor(typescript): centralize auth wrapper property handling

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test: fix fixture generators.yml branch names

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(test): add response examples to TypeScript fixture

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(cli): refresh IR snapshots after main merge

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test: align ts-flatten-request-any-auth example ids for wire tests

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore(typescript): point dynamic-ir-sdk compat TODO at IR 67.27.0

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: rerun CI

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(typescript): use camelCase scheme key for auth wrapper regardless of serde config

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(typescript): match SDK oauth wrapper key casing in dynamic snippets

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: dakshesh.daruri <dakshesh.daruri@postman.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dak <dakshesh@buildwithfern.com>
devin-ai-integration Bot added a commit that referenced this pull request Sep 16, 2026
…7746)

* fix(typescript): match SDK request/auth shape in dynamic snippets

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore(typescript): address review nits on dynamic snippet auth/flatten

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(typescript): drop path params that collide with flattened body fields in snippets

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(cli): update auth wrapperProperty snapshots

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(cli): add TypeScript flattening fixture snapshots

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(ts-sdk): add flattening seed fixture output

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(typescript): cover real fixture dynamic snippets

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor(typescript): centralize auth wrapper property handling

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test: fix fixture generators.yml branch names

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(test): add response examples to TypeScript fixture

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(cli): refresh IR snapshots after main merge

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test: align ts-flatten-request-any-auth example ids for wire tests

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore(typescript): point dynamic-ir-sdk compat TODO at IR 67.27.0

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: rerun CI

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(typescript): use camelCase scheme key for auth wrapper regardless of serde config

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(typescript): match SDK oauth wrapper key casing in dynamic snippets

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: dakshesh.daruri <dakshesh.daruri@postman.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dak <dakshesh@buildwithfern.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants