Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(types): fix client type transforms #1389

Merged
merged 1 commit into from
Sep 5, 2024
Merged

Conversation

kuhe
Copy link
Contributor

@kuhe kuhe commented Sep 5, 2024

aws/aws-sdk-js-v3#4720

This PR fixes typechecking for aggregated client usage in the optional type transforms from changes to the Command shapes using Command.classBuilder.

preview of the integration test I'll add to AWS SDK:

import { GetObjectCommand, S3, S3Client } from "@aws-sdk/client-s3";
import type { AssertiveClient, BrowserClient, NodeJsClient, UncheckedClient } from "@smithy/types";

{
  // default, no validation for undefined values
  const s3 = new S3({});

  await s3.listBuckets();
  await s3.listBuckets({});

  // @ts-expect-error (missing Bucket)
  s3.getObject({
    Key: undefined,
  });

  s3.getObject({
    // @ts-expect-error (unrecognized field)
    UnknownProperty: undefined,
  });

  const get = await s3.getObject({
    Bucket: undefined,
    Key: undefined,
  });

  // @ts-expect-error (Body may be undefined)
  await get.Body.transformToString();

  await get.Body?.transformToString();
  await get.Body!.transformToString();
}

{
  // the assertive client requires that inputs/outputs are of the right type
  // excluding '| undefined'.
  const s3_assertive = new S3() as AssertiveClient<S3>;
  const s3Client_assertive = new S3Client() as AssertiveClient<S3Client>;

  await s3_assertive.listBuckets();
  await s3_assertive.listBuckets({});

  s3_assertive.getObject({
    Bucket: "undefined",
    // @ts-expect-error (undefined not assignable to string)
    Key: undefined,
  });
  s3Client_assertive.send(
    new GetObjectCommand({
      Bucket: "undefined",
      // type transform is unable to validate within Command ctor.
      Key: undefined,
    })
  );

  // @ts-expect-error (missing Key)
  s3_assertive.getObject({
    Bucket: "undefined",
  });

  {
    const get = await s3_assertive.getObject({
      Bucket: "undefined",
      Key: "undefined",
    });

    // @ts-expect-error (Body is optional)
    await get.Body.transformToString();

    await get.Body?.transformToString();
    await get.Body!.transformToString();
  }

  {
    const get = await s3Client_assertive.send(
      new GetObjectCommand({
        Bucket: "undefined",
        Key: "undefined",
      })
    );

    // @ts-expect-error (Body is optional)
    await get.Body.transformToString();

    await get.Body?.transformToString();
    await get.Body!.transformToString();
  }
}

{
  // unchecked client also removes the possibility
  // of optionality '?' in addition to '| undefined'.
  const s3_unchecked = new S3({}) as UncheckedClient<S3>;
  const s3Client_unchecked = new S3Client() as UncheckedClient<S3Client>;

  await s3_unchecked.listBuckets();
  await s3_unchecked.listBuckets({});

  s3_unchecked.getObject({
    Bucket: "undefined",
    // @ts-expect-error (undefined not assignable to string)
    Key: undefined,
  });
  s3_unchecked.send(
    new GetObjectCommand({
      Bucket: "undefined",
      // type transform is unable to validate within Command ctor.
      Key: undefined,
    })
  );

  // @ts-expect-error (missing Key)
  s3_unchecked.getObject({
    Bucket: "undefined",
  });

  {
    const get = await s3_unchecked.getObject({
      Bucket: "undefined",
      Key: "undefined",
    });

    await get.Body.transformToString();
  }

  {
    const get = await s3Client_unchecked.send(
      new GetObjectCommand({
        Bucket: "undefined",
        Key: "undefined",
      })
    );

    await get.Body.transformToString();
  }
}

{
  // platform specific clients.
  const s3_browser = new S3({}) as BrowserClient<S3>;
  const s3Client_browser = new S3Client() as BrowserClient<S3Client>;
  const s3_node = new S3() as NodeJsClient<S3>;
  const s3Client_node = new S3() as NodeJsClient<S3>;

  {
    const get = await s3Client_browser.send(
      new GetObjectCommand({
        Bucket: "undefined",
        Key: "undefined",
      })
    );
    get.Body!.tee();
  }
  {
    const get = await s3_browser.getObject({ Bucket: "undefined", Key: "undefined" });
    get.Body!.tee();
  }

  {
    const get = await s3Client_node.send(
      new GetObjectCommand({
        Bucket: "undefined",
        Key: "undefined",
      })
    );
    get.Body!.pause();
  }
  {
    const get = await s3_node.getObject({ Bucket: "undefined", Key: "undefined" });
    get.Body!.pause();
  }
}

@kuhe kuhe requested review from a team as code owners September 5, 2024 01:04
@kuhe kuhe force-pushed the fix/types branch 3 times, most recently from c9430ed to 861f92e Compare September 5, 2024 01:13
@kuhe kuhe force-pushed the fix/types branch 3 times, most recently from 710bffc to 0f50cc5 Compare September 5, 2024 15:56
@kuhe kuhe merged commit 9f3f2f5 into smithy-lang:main Sep 5, 2024
11 checks passed
@kuhe kuhe deleted the fix/types branch September 5, 2024 18:38
This pull request was closed.
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.

3 participants