- SDKs
+
+ SDKs
+
- The SumUp SDKs reduce the amount of work required to use our REST
- APIs. SumUp maintains SDKs for PHP, JavaScript, Python, Java, Go,
- Rust, and .NET.
+ The SumUp SDKs and command-line interface reduce the amount of work
+ required to use our REST APIs. Use the CLI directly from your
+ terminal, or choose an SDK for PHP, JavaScript, Python, Java, Go,
+ Rust, or .NET.
@@ -89,7 +92,12 @@ const sectionAttrs = (id: ApiTopSection) =>
options={[
{
label: "cURL",
- code: "# Select a client library to see installation instructions.",
+ code: "# Select the CLI or an SDK to see installation instructions.",
+ lang: "bash",
+ },
+ {
+ label: "CLI",
+ code: "brew install sumup/cli/sumup",
lang: "bash",
},
{
@@ -146,7 +154,7 @@ uv add sumup`,
]}
isLanguageSelect
>
-
Install SDK
+
Install
@@ -197,6 +205,11 @@ uv add sumup`,
-H "Authorization: Bearer sup_sk_MvxmLOl0..."`,
lang: "bash",
},
+ {
+ label: "CLI",
+ code: "export SUMUP_API_KEY='sup_sk_MvxmLOl0...'",
+ lang: "bash",
+ },
{
label: "JavaScript",
code: `import { SumUp } from '@sumup/sdk';
diff --git a/src/content.config.ts b/src/content.config.ts
index c626a5b6..377fa0f2 100644
--- a/src/content.config.ts
+++ b/src/content.config.ts
@@ -1,7 +1,8 @@
import { docsLoader } from "@astrojs/starlight/loaders";
import { docsSchema } from "@astrojs/starlight/schema";
import { glob } from "astro/loaders";
-import { defineCollection, z } from "astro:content";
+import { z } from "astro/zod";
+import { defineCollection } from "astro:content";
import { openapiDescriptionsLoader } from "./loaders/openapiDescriptions";
const help = defineCollection({
diff --git a/src/content/docs/online-payments/checkouts/index.mdx b/src/content/docs/online-payments/checkouts/index.mdx
index 43fd684b..65d8580e 100644
--- a/src/content/docs/online-payments/checkouts/index.mdx
+++ b/src/content/docs/online-payments/checkouts/index.mdx
@@ -13,4 +13,5 @@ SumUp provides the following checkout integrations for online payments:
- [Hosted Checkout](/online-payments/checkouts/hosted-checkout/) - SumUp-hosted payment page with minimal integration effort
- [Swift Checkout SDK](/online-payments/checkouts/swift-checkout/) - accelerated wallet checkout for Apple Pay and Google Pay
- [Server-side SDKs](/tools/sdks/) - JavaScript, Go, Python, Java, PHP, .NET, and Rust clients for the SumUp API
+- [SumUp CLI](/tools/cli/) - command-line access to the SumUp API for development and automation
- [React Native SDK](/online-payments/sdks/react-native/) - payment sheet for mobile apps
diff --git a/src/content/docs/online-payments/guides/index.mdx b/src/content/docs/online-payments/guides/index.mdx
index 2337a01a..368eaa9f 100644
--- a/src/content/docs/online-payments/guides/index.mdx
+++ b/src/content/docs/online-payments/guides/index.mdx
@@ -36,4 +36,4 @@ With your sandbox merchant account, begin making API calls with real data. Sandb
When finished experimenting with the sandbox merchant account, switch back to a regular account for business purposes.
-SumUp provides official SDKs for JavaScript, Go, Python, Java, PHP, .NET, and Rust — visit the [SDKs overview page](/tools/sdks/) to choose the client that fits your stack.
+SumUp provides official SDKs for JavaScript, Go, Python, Java, PHP, .NET, and Rust, as well as the [SumUp CLI](/tools/cli/) for working from a terminal. Visit the [SDKs overview page](/tools/sdks/) to choose the client that fits your stack.
diff --git a/src/content/docs/tools/cli.mdx b/src/content/docs/tools/cli.mdx
new file mode 100644
index 00000000..f2810ed2
--- /dev/null
+++ b/src/content/docs/tools/cli.mdx
@@ -0,0 +1,118 @@
+---
+title: CLI
+description: Install and use the SumUp command-line interface to interact with SumUp APIs from your terminal.
+sidebar:
+ order: 101
+links:
+ - title: Source code
+ href: https://github.com/sumup/sumup-cli
+ - title: Releases
+ href: https://github.com/sumup/sumup-cli/releases
+---
+
+The SumUp CLI, `sumup`, lets you manage your SumUp account and call SumUp APIs from a terminal. Use it to explore API operations, run development workflows, or write scripts without setting up an SDK project.
+
+The [API reference](/api/) includes a **CLI** sample for every operation supported by the tool.
+
+## Install the CLI
+
+Install the CLI with [Homebrew](https://brew.sh/):
+
+```bash
+brew install sumup/cli/sumup
+```
+
+Alternatively, install it with Go:
+
+```bash
+go install github.com/sumup/sumup-cli/cmd/sumup
+```
+
+Confirm that the installation succeeded:
+
+```bash
+sumup version
+```
+
+## Configure Authentication
+
+Create a secret API key in the [developer dashboard](https://me.sumup.com/developers), then expose it to the CLI through the `SUMUP_API_KEY` environment variable:
+
+```bash
+export SUMUP_API_KEY=sup_sk_your_api_key
+```
+
+You can also pass an API key with the global `--api-key` option. Avoid saving secret API keys in shell history or source control.
+
+## Set Your Merchant Context
+
+Commands that operate on a merchant accept the `--merchant-code` option. To avoid repeating it, select a merchant interactively and save it as your current context:
+
+```bash
+sumup context set
+```
+
+View or clear the saved context with:
+
+```bash
+sumup context get
+sumup context unset
+```
+
+An explicit `--merchant-code` option overrides the saved context.
+
+## Run Commands
+
+Create an online checkout:
+
+```bash
+sumup checkouts create \
+ --reference order-123 \
+ --amount 19.99 \
+ --currency EUR \
+ --merchant-code M123 \
+ --description "Ticket purchase"
+```
+
+List the readers paired with a merchant:
+
+```bash
+sumup readers list --merchant-code M123
+```
+
+Add the global `--json` option when a script needs machine-readable output:
+
+```bash
+sumup --json readers list --merchant-code M123
+```
+
+Use the built-in help to discover available resources, operations, and options:
+
+```bash
+sumup --help
+sumup checkouts --help
+sumup checkouts create --help
+```
+
+## Enable Shell Completion
+
+Generate and load a completion script for your shell:
+
+```bash
+# bash
+source <(sumup completion bash)
+
+# zsh
+source <(sumup completion zsh)
+
+# fish
+sumup completion fish > ~/.config/fish/completions/sumup.fish
+```
+
+Release archives also include pre-generated completion scripts and a man page.
+
+## Next Steps
+
+- Browse the [API reference](/api/) and select the **CLI** tab for operation-specific commands.
+- Review [authorization options](/tools/authorization/) before using the CLI with production accounts.
+- Use an [official server SDK](/tools/sdks/) when you need typed clients and application-level integration.
diff --git a/src/content/docs/tools/sdks/index.mdx b/src/content/docs/tools/sdks/index.mdx
index e520ae3b..59617b86 100644
--- a/src/content/docs/tools/sdks/index.mdx
+++ b/src/content/docs/tools/sdks/index.mdx
@@ -1,6 +1,6 @@
---
title: SDKs
-description: Build on SumUp's APIs with officially supported server-side SDKs.
+description: Build on SumUp's APIs with the SumUp CLI or an officially supported server-side SDK.
sidebar:
label: Overview
order: 100
@@ -8,6 +8,8 @@ sidebar:
SumUp maintains open-source server SDKs that wrap the public API and handle authentication, pagination, and resource helpers. You can use the same SDK for online payments and for card-present payments through the Cloud API. Each guide includes examples for creating an online checkout and starting a checkout on a paired Solo reader.
+Prefer working from a terminal? The [SumUp CLI](/tools/cli/) provides commands for SumUp API operations without requiring you to write an application.
+
## Choose Your SDK
- **[JavaScript](/tools/sdks/javascript/)** – published on npm as `@sumup/sdk` with first-class TypeScript typings and ESM support across JavaScript runtimes.
diff --git a/src/content/help/support-libraries.mdx b/src/content/help/support-libraries.mdx
index 33075c8f..b0e91b1e 100644
--- a/src/content/help/support-libraries.mdx
+++ b/src/content/help/support-libraries.mdx
@@ -9,6 +9,11 @@ SumUp maintains multiple SDKs and APIs to simplify your integration work across
- [JavaScript / TypeScript, Go, Python, Java, PHP, .NET, and Rust SDK guides](/tools/sdks/) cover server-to-SumUp API calls for online payments and remote Solo reader management through the Cloud API.
- Use these when you’re building checkout pages, recurring billing, or card-present integrations from a backend or platform that can make API requests.
+## Command Line Interface
+
+- The [SumUp CLI](/tools/cli/) lets you call SumUp APIs from a terminal without writing an application.
+- Use it for exploring operations, development workflows, and scripts that consume JSON output.
+
## Card-Present Integrations
- [Android SDK](https://github.com/sumup/sumup-android-sdk) and [iOS SDK](https://github.com/sumup/sumup-ios-sdk) let you embed our reader experience inside native apps.
diff --git a/src/lib/codesamples/dotnet.ts b/src/lib/codesamples/dotnet.ts
deleted file mode 100644
index 06f27cf6..00000000
--- a/src/lib/codesamples/dotnet.ts
+++ /dev/null
@@ -1,208 +0,0 @@
-import { resolveSchema } from "@lib/openapi";
-import { Case } from "change-case-all";
-import type { OpenAPIV3_1 } from "openapi-types";
-import type { OperationObject } from "src/types/openapi";
-import { getParameterExample, getRequestBodyExample } from "./util";
-
-const INDENT = " ";
-
-const indentMultiline = (text: string, indent: string): string => {
- return text.replace(/\n/g, `\n${indent}`);
-};
-
-const formatPrimitive = (value: string | number | boolean | null): string => {
- if (typeof value === "string") {
- return JSON.stringify(value);
- }
-
- if (typeof value === "number" || typeof value === "boolean") {
- return `${value}`;
- }
-
- if (value === null) {
- return "null";
- }
-
- return "null";
-};
-
-const getSchemaTypeName = (
- schema: OpenAPIV3_1.ReferenceObject | OpenAPIV3_1.SchemaObject,
- fallback: string,
-): string => {
- if ("$ref" in schema) {
- return Case.pascal(schema.$ref.split("/").pop()!);
- }
-
- if ("title" in schema && schema.title) {
- return Case.pascal(schema.title);
- }
-
- return Case.pascal(fallback);
-};
-
-const generateArrayInitializer = (
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- values: any[],
- schema: OpenAPIV3_1.SchemaObject,
- indentLevel: number,
- propertyName: string,
-): string => {
- if (values.length === 0) {
- return "Array.Empty()";
- }
-
- const firstValue = values[0];
-
- if (typeof firstValue === "object" && firstValue !== null) {
- const itemsSchema =
- "items" in schema && schema.items ? resolveSchema(schema.items) : {};
- const typeName =
- "items" in schema && schema.items
- ? getSchemaTypeName(schema.items, `${Case.pascal(propertyName)}Item`)
- : `${Case.pascal(propertyName)}Item`;
-
- const collectionIndent = INDENT.repeat(indentLevel);
- const itemIndent = INDENT.repeat(indentLevel + 1);
-
- const items = values
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- .map((item: any) => {
- const objectInit = generateCSharpObjectInitializer(
- item,
- itemsSchema as OpenAPIV3_1.SchemaObject,
- typeName,
- indentLevel + 1,
- );
-
- return `${itemIndent}${indentMultiline(objectInit, itemIndent)},`;
- })
- .join("\n");
-
- return `new[]\n${collectionIndent}{\n${items}\n${collectionIndent}}`;
- }
-
- const primitiveValues = values.map((value) => formatPrimitive(value));
- return `new[] { ${primitiveValues.join(", ")} }`;
-};
-
-const generateCSharpObjectInitializer = (
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- example: any,
- schema: OpenAPIV3_1.SchemaObject,
- typeName: string,
- indentLevel = 0,
-): string => {
- if (!example || typeof example !== "object") {
- return "";
- }
-
- const indent = INDENT.repeat(indentLevel);
- const fieldIndent = INDENT.repeat(indentLevel + 1);
- const properties = schema.properties || {};
-
- const fields = Object.entries(example)
- .map(([key, value]) => {
- const propertyName = Case.pascal(key);
- const propSchema = properties[key];
-
- if (!propSchema) {
- return `${fieldIndent}${propertyName} = ${formatPrimitive(value as never)},`;
- }
-
- const resolved = resolveSchema(propSchema);
-
- if (
- value !== null &&
- typeof value === "object" &&
- !Array.isArray(value)
- ) {
- const nestedTypeName = getSchemaTypeName(propSchema, propertyName);
- const nestedInit = generateCSharpObjectInitializer(
- value,
- resolved,
- nestedTypeName,
- indentLevel + 1,
- );
-
- return `${fieldIndent}${propertyName} = ${nestedInit},`;
- }
-
- if (Array.isArray(value)) {
- const arrayInit = generateArrayInitializer(
- value,
- resolved,
- indentLevel + 1,
- propertyName,
- );
-
- return `${fieldIndent}${propertyName} = ${arrayInit},`;
- }
-
- return `${fieldIndent}${propertyName} = ${formatPrimitive(value as never)},`;
- })
- .join("\n");
-
- return `new ${typeName}\n${indent}{\n${fields}\n${indent}}`;
-};
-
-const requestBody = (operation: OperationObject): string => {
- const requestBodySchema =
- operation.requestBody?.content?.["application/json"]?.schema;
- if (!requestBodySchema) {
- return "";
- }
-
- const schema = resolveSchema(requestBodySchema);
-
- if (!schema || !schema.properties) {
- return "";
- }
-
- const example = getRequestBodyExample(operation);
-
- if (!example || typeof example !== "object") {
- return "";
- }
-
- const typeName = getSchemaTypeName(
- requestBodySchema,
- `${Case.pascal(operation.operationId!)}Body`,
- );
-
- return generateCSharpObjectInitializer(example, schema, typeName);
-};
-
-const formatArgument = (argument: string): string => {
- return `${INDENT}${indentMultiline(argument, INDENT)}`;
-};
-
-export const dotnet = (operation: OperationObject): string => {
- const resource = Case.pascal(operation.tag);
- const methodName = Case.pascal(
- operation["x-codegen"]?.method_name || operation.operationId!,
- );
-
- const requiredParams = operation.parameters?.filter((p) => p.required) || [];
- const paramArgs = requiredParams.map((param) => {
- return formatPrimitive(getParameterExample(param) as never);
- });
-
- const bodyArg = requestBody(operation);
- const args = [...paramArgs];
-
- if (bodyArg) {
- args.push(bodyArg);
- }
-
- const formattedArgs =
- args.length > 0
- ? `\n${args.map((arg) => formatArgument(arg)).join(",\n")}\n`
- : "";
-
- return `using SumUp;
-
-var client = new SumUpClient();
-
-var result = await client.${resource}.${methodName}Async(${formattedArgs});`;
-};
diff --git a/src/lib/codesamples/go.ts b/src/lib/codesamples/go.ts
deleted file mode 100644
index 04e83896..00000000
--- a/src/lib/codesamples/go.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-import { resolveSchema } from "@lib/openapi";
-import { Case } from "change-case-all";
-import type { OpenAPIV3_1 } from "openapi-types";
-import type { OperationObject } from "src/types/openapi";
-import { getRequestBodyExample, getParameterExample } from "./util";
-
-/**
- * Generates Go struct initialization code from an example object.
- */
-const generateGoStructInit = (
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- example: any,
- schema: OpenAPIV3_1.SchemaObject,
- indent = "",
-): string => {
- if (example === null || example === undefined) {
- return "";
- }
-
- const properties = schema.properties || {};
-
- const fields = Object.entries(example)
- .map(([key, value]) => {
- const fieldName = Case.pascal(key);
- const propSchema = properties[key];
-
- if (!propSchema) {
- // Fallback for unknown properties
- return `${indent} ${fieldName}: ${JSON.stringify(value)},`;
- }
-
- const resolved = resolveSchema(propSchema);
-
- // Handle nested objects
- if (
- typeof value === "object" &&
- value !== null &&
- !Array.isArray(value)
- ) {
- // Get the struct name from $ref or use schema title/key
- let structName = "";
- if ("$ref" in propSchema) {
- structName = Case.pascal(propSchema.$ref.split("/").pop()!);
- } else if (resolved.title) {
- structName = Case.pascal(resolved.title);
- } else {
- structName = Case.pascal(key);
- }
-
- const nestedInit = generateGoStructInit(value, resolved, indent + " ");
- return `${indent} ${fieldName}: sumup.${structName}${nestedInit},`;
- }
-
- // Handle arrays
- if (Array.isArray(value)) {
- if (value.length === 0) {
- return `${indent} ${fieldName}: []any{},`;
- }
-
- const firstItem = value[0];
- if (typeof firstItem === "object" && firstItem !== null) {
- // Array of objects
- let itemStructName = "";
- if (
- "items" in resolved &&
- resolved.items &&
- "$ref" in resolved.items
- ) {
- itemStructName = Case.pascal(resolved.items.$ref.split("/").pop()!);
- } else if (
- "items" in resolved &&
- resolved.items &&
- "title" in resolved.items &&
- resolved.items.title
- ) {
- itemStructName = Case.pascal(resolved.items.title);
- } else {
- itemStructName = Case.pascal(key);
- }
-
- const itemsInit = value
- .map((item) => {
- const itemSchema =
- "items" in resolved && resolved.items
- ? resolveSchema(resolved.items)
- : {};
- return `${indent} sumup.${itemStructName}${generateGoStructInit(item, itemSchema as OpenAPIV3_1.SchemaObject, indent + " ")}`;
- })
- .join(",\n");
-
- return `${indent} ${fieldName}: []sumup.${itemStructName}{\n${itemsInit},\n${indent} },`;
- }
-
- // Array of primitives
- return `${indent} ${fieldName}: ${JSON.stringify(value)},`;
- }
-
- // Primitives
- return `${indent} ${fieldName}: ${JSON.stringify(value)},`;
- })
- .join("\n");
-
- return `{\n${fields}\n${indent}}`;
-};
-
-const requestBody = (
- operation: OperationObject,
- methodName: string,
-): string => {
- const example = getRequestBodyExample(operation);
-
- if (!example || typeof example !== "object") {
- return "";
- }
-
- const requestBodySchema =
- operation.requestBody?.content?.["application/json"]?.schema;
- if (!requestBodySchema) {
- return "";
- }
-
- const schema = resolveSchema(requestBodySchema);
- if (!schema || !schema.properties) {
- return "";
- }
-
- const bodyStructName = `${Case.pascal(operation.tag)}${Case.pascal(methodName)}Params`;
-
- return `sumup.${bodyStructName}${generateGoStructInit(example, schema)}`;
-};
-
-export const go = (operation: OperationObject): string => {
- const resource = Case.pascal(operation.tag);
- const methodName =
- operation["x-codegen"]?.method_name || operation.operationId || "";
- const method = Case.pascal(methodName);
-
- const body = requestBody(operation, methodName);
-
- // Extract required parameters and use their examples from referenced schemas if available
- const requiredParams = operation.parameters?.filter((p) => p.required) || [];
- const paramsString = requiredParams
- .map((param) => JSON.stringify(getParameterExample(param)))
- .join(", ");
-
- const go = `client := sumup.NewClient()
-
-result, err := client.${resource}.${method}(context.Background()${paramsString ? `, ${paramsString}` : ""}${body ? `, ${body}` : ""})`;
-
- return go;
-};
diff --git a/src/lib/codesamples/index.test.ts b/src/lib/codesamples/index.test.ts
index ee099f01..be55cd55 100644
--- a/src/lib/codesamples/index.test.ts
+++ b/src/lib/codesamples/index.test.ts
@@ -1,15 +1,23 @@
import { describe, expect, it } from "vitest";
import type { OpenAPIV3_1 } from "openapi-types";
+import cliSamples from "../../codesamples/cli.json";
+import dotnetSamples from "../../codesamples/dotnet.json";
+import goSamples from "../../codesamples/go.json";
+import javaSamples from "../../codesamples/java.json";
+import pythonSamples from "../../codesamples/python.json";
+import rustSamples from "../../codesamples/rust.json";
+import typescriptSamples from "../../codesamples/typescript.json";
import type { OperationObject } from "../../types/openapi";
import {
+ cli,
curl,
dotnet,
go,
java,
- node as nodeSample,
php,
python,
rust,
+ typescript,
} from "./index";
const checkoutBodySchema: OpenAPIV3_1.SchemaObject = {
@@ -73,153 +81,34 @@ const checkoutOperation: OperationObject = {
},
};
-const updateCustomerBodySchema: OpenAPIV3_1.SchemaObject = {
- type: "object",
- required: ["email"],
- properties: {
- email: {
- type: "string",
- example: "ada@example.com",
- },
- },
-};
-
-const updateCustomerOperation: OperationObject = {
- operationId: "UpdateCustomer",
- tag: "Customers",
- slug: "customers-update",
- tagSlug: "customers",
- summary: "Update customer",
- description: "Updates a customer profile.",
- method: "PUT",
- path: "/v0.1/customers/{customer_id}",
- "x-codegen": {
- method_name: "update",
- },
- parameters: [
- {
- name: "customer_id",
- in: "path",
- required: true,
- schema: {
- type: "string",
- example: "cust_123",
- },
- },
- {
- name: "fields",
- in: "query",
- required: false,
- schema: {
- type: "string",
- example: "personal_details",
- },
- },
- ],
- requestBody: {
- content: {
- "application/json": {
- schema: updateCustomerBodySchema,
- example: {
- email: "ada@example.com",
- },
- },
- },
- },
- responses: {
- "200": {
- description: "Updated",
- },
- },
-};
-
-describe("code sample generators", () => {
- it("node sample matches the TypeScript SDK usage", () => {
- expect(nodeSample(checkoutOperation)).toBe(
- `import SumUp from '@sumup/sdk';
-
-const client = new SumUp();
-
-const result = await client.checkouts.create("MC123", {
- amount: 1000,
- currency: "EUR",
- description: "Online order #42",
-});`,
- );
- });
-
- it("python sample uses the Sumup SDK client", () => {
- expect(python(checkoutOperation)).toBe(
- `from sumup import Sumup
-
-client = Sumup()
-
-result = client.checkouts.create("MC123", CreateCheckoutBody(
- amount=1000,
- currency="EUR",
- description="Online order #42",
-))`,
+describe("code samples", () => {
+ it.each([
+ ["Python", python, pythonSamples],
+ [".NET", dotnet, dotnetSamples],
+ ["Go", go, goSamples],
+ ["Java", java, javaSamples],
+ ["Rust", rust, rustSamples],
+ ["TypeScript", typescript, typescriptSamples],
+ ["CLI", cli, cliSamples],
+ ])("uses the vendored %s sample", (_, codeSample, vendoredSamples) => {
+ const expected = vendoredSamples.samples.find(
+ ({ operationId }) => operationId === checkoutOperation.operationId,
);
- });
-
- it("dotnet sample uses the SumUp .NET client", () => {
- expect(dotnet(checkoutOperation)).toBe(
- `using SumUp;
-
-var client = new SumUpClient();
-
-var result = await client.Checkouts.CreateAsync(
- "MC123",
- new CreateCheckoutBody
- {
- Amount = 1000,
- Currency = "EUR",
- Description = "Online order #42",
- }
-);`,
- );
- });
- it("go sample renders struct initialisers", () => {
- expect(go(checkoutOperation)).toBe(
- `client := sumup.NewClient()
-
-result, err := client.Checkouts.Create(context.Background(), "MC123", sumup.CheckoutsCreateParams{
- Amount: 1000,
- Currency: "EUR",
- Description: "Online order #42",
-})`,
- );
+ expect(codeSample(checkoutOperation)).toBe(expected?.sample);
});
- it("java sample uses the SumUp client", () => {
- expect(java(checkoutOperation)).toBe(
- `import com.sumup.sdk.SumUpClient;
+ it("fails clearly when a vendored sample is missing", () => {
+ const operation = {
+ ...checkoutOperation,
+ operationId: "UnknownOperation",
+ };
-SumUpClient client = SumUpClient.builder().build();
-
-var result = client.checkouts().createCheckout(
- "MC123",
- CreateCheckoutBody.builder()
- .amount(1000f)
- .currency("EUR")
- .description("Online order #42")
- .build()
-);`,
+ expect(() => go(operation)).toThrow(
+ "Missing go code sample for UnknownOperation",
);
- });
-
- it("rust sample includes params and body examples", () => {
- expect(rust(updateCustomerOperation)).toBe(
- `use sumup::Client;
-
-let client = Client::default();
-
-let result = client.customers().update("cust_123", sumup::UpdateCustomerParams{
- fields: Some("personal_details".to_string()),
-}, sumup::UpdateCustomerBody{
- email: "ada@example.com".to_string(),
-}).await;`,
+ expect(() => cli(operation)).toThrow(
+ "Missing bash code sample for UnknownOperation",
);
});
diff --git a/src/lib/codesamples/index.ts b/src/lib/codesamples/index.ts
index 3470ef17..37469d89 100644
--- a/src/lib/codesamples/index.ts
+++ b/src/lib/codesamples/index.ts
@@ -1,10 +1,68 @@
+import cliSamples from "../../codesamples/cli.json";
+import dotnetSamples from "../../codesamples/dotnet.json";
+import goSamples from "../../codesamples/go.json";
+import javaSamples from "../../codesamples/java.json";
+import pythonSamples from "../../codesamples/python.json";
+import rustSamples from "../../codesamples/rust.json";
+import typescriptSamples from "../../codesamples/typescript.json";
+import type { OperationObject } from "../../types/openapi";
import { curl } from "./curl";
-import { dotnet } from "./dotnet";
-import { go } from "./go";
-import { java } from "./java";
-import { node } from "./node";
import { php } from "./php";
-import { python } from "./python";
-import { rust } from "./rust";
-export { curl, dotnet, go, java, node, php, python, rust };
+type CodeSamples = {
+ language: string;
+ samples: {
+ operationId: string;
+ sample: string;
+ }[];
+};
+
+const samplesByOperationId = (codeSamples: CodeSamples) => {
+ const samples = new Map();
+
+ // The API page shows one sample per language, so use the first example when
+ // an operation has multiple vendored variants.
+ for (const sample of codeSamples.samples) {
+ if (!samples.has(sample.operationId)) {
+ samples.set(sample.operationId, sample.sample);
+ }
+ }
+
+ return samples;
+};
+
+const findVendoredSample = (codeSamples: CodeSamples) => {
+ const samples = samplesByOperationId(codeSamples);
+
+ return (operation: OperationObject): string | undefined => {
+ return operation.operationId
+ ? samples.get(operation.operationId)
+ : undefined;
+ };
+};
+
+const fromVendoredSamples = (codeSamples: CodeSamples) => {
+ const findSample = findVendoredSample(codeSamples);
+
+ return (operation: OperationObject): string => {
+ const sample = findSample(operation);
+
+ if (!sample) {
+ throw new Error(
+ `Missing ${codeSamples.language} code sample for ${operation.operationId ?? "operation without an ID"}`,
+ );
+ }
+
+ return sample;
+ };
+};
+
+const cli = fromVendoredSamples(cliSamples);
+const dotnet = fromVendoredSamples(dotnetSamples);
+const go = fromVendoredSamples(goSamples);
+const java = fromVendoredSamples(javaSamples);
+const python = fromVendoredSamples(pythonSamples);
+const rust = fromVendoredSamples(rustSamples);
+const typescript = fromVendoredSamples(typescriptSamples);
+
+export { cli, curl, dotnet, go, java, php, python, rust, typescript };
diff --git a/src/lib/codesamples/java.ts b/src/lib/codesamples/java.ts
deleted file mode 100644
index 437f8a7a..00000000
--- a/src/lib/codesamples/java.ts
+++ /dev/null
@@ -1,237 +0,0 @@
-import { resolveSchema } from "@lib/openapi";
-import { Case } from "change-case-all";
-import type { OpenAPIV3_1 } from "openapi-types";
-import type { OperationObject } from "src/types/openapi";
-import { getParameterExample, getRequestBodyExample } from "./util";
-
-const INDENT = " ";
-
-const indentMultiline = (text: string, indent: string): string => {
- return text.replace(/\n/g, `\n${indent}`);
-};
-
-const getSchemaTypeName = (
- schema: OpenAPIV3_1.ReferenceObject | OpenAPIV3_1.SchemaObject,
- fallback: string,
-): string => {
- if ("$ref" in schema) {
- return Case.pascal(schema.$ref.split("/").pop()!);
- }
-
- if ("title" in schema && schema.title) {
- return Case.pascal(schema.title);
- }
-
- return Case.pascal(fallback);
-};
-
-const formatPrimitive = (
- value: string | number | boolean | null,
- schema?: OpenAPIV3_1.SchemaObject,
-): string => {
- if (value === null) {
- return "null";
- }
-
- if (typeof value === "string") {
- if (schema?.format === "date-time") {
- return `java.time.OffsetDateTime.parse(${JSON.stringify(value)})`;
- }
-
- if (schema?.format === "date") {
- return `java.time.LocalDate.parse(${JSON.stringify(value)})`;
- }
-
- return JSON.stringify(value);
- }
-
- if (typeof value === "number") {
- if (schema?.type === "integer") {
- if (schema.format === "int64") {
- return `${value}L`;
- }
-
- return `${value}`;
- }
-
- if (schema?.type === "number") {
- return Number.isInteger(value) ? `${value}f` : `${value}f`;
- }
-
- return `${value}`;
- }
-
- if (typeof value === "boolean") {
- return value ? "true" : "false";
- }
-
- return "null";
-};
-
-const isEnumSchema = (schema: OpenAPIV3_1.SchemaObject): boolean => {
- return Array.isArray(schema.enum) && schema.enum.length > 0;
-};
-
-const formatEnum = (value: string, typeName: string): string => {
- return `${typeName}.fromValue(${JSON.stringify(value)})`;
-};
-
-const formatArray = (
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- values: any[],
- schema: OpenAPIV3_1.SchemaObject,
- indentLevel: number,
- propertyName: string,
-): string => {
- if (values.length === 0) {
- return "java.util.List.of()";
- }
-
- const itemSchema =
- "items" in schema && schema.items ? resolveSchema(schema.items) : {};
- const itemTypeName =
- "items" in schema && schema.items
- ? getSchemaTypeName(schema.items, `${Case.pascal(propertyName)}Item`)
- : `${Case.pascal(propertyName)}Item`;
-
- const arrayIndent = INDENT.repeat(indentLevel);
- const itemIndent = INDENT.repeat(indentLevel + 1);
-
- const items = values
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- .map((item: any) => {
- if (item !== null && typeof item === "object") {
- const objectInit = generateJavaBuilder(
- item,
- itemSchema as OpenAPIV3_1.SchemaObject,
- itemTypeName,
- indentLevel + 1,
- );
-
- return `${itemIndent}${indentMultiline(objectInit, itemIndent)}`;
- }
-
- return `${itemIndent}${formatPrimitive(item as never, itemSchema as OpenAPIV3_1.SchemaObject)}`;
- })
- .join(",\n");
-
- return `java.util.List.of(\n${items}\n${arrayIndent})`;
-};
-
-const generateJavaBuilder = (
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- example: any,
- schema: OpenAPIV3_1.SchemaObject,
- typeName: string,
- indentLevel = 0,
-): string => {
- if (!example || typeof example !== "object") {
- return "";
- }
-
- const fieldIndent = INDENT.repeat(indentLevel + 1);
- const properties = schema.properties || {};
-
- const fields = Object.entries(example)
- .map(([key, value]) => {
- const methodName = Case.camel(key);
- const propSchema = properties[key];
-
- if (!propSchema) {
- return `${fieldIndent}.${methodName}(${formatPrimitive(value as never)})`;
- }
-
- const resolved = resolveSchema(propSchema);
-
- if (resolved && isEnumSchema(resolved) && typeof value === "string") {
- const enumTypeName = getSchemaTypeName(propSchema, key);
- return `${fieldIndent}.${methodName}(${formatEnum(value, enumTypeName)})`;
- }
-
- if (
- value !== null &&
- typeof value === "object" &&
- !Array.isArray(value)
- ) {
- const nestedTypeName = getSchemaTypeName(propSchema, key);
- const nestedInit = generateJavaBuilder(
- value,
- resolved,
- nestedTypeName,
- indentLevel + 1,
- );
-
- return `${fieldIndent}.${methodName}(${indentMultiline(nestedInit, fieldIndent)})`;
- }
-
- if (Array.isArray(value)) {
- const arrayInit = formatArray(value, resolved, indentLevel + 1, key);
-
- return `${fieldIndent}.${methodName}(${indentMultiline(arrayInit, fieldIndent)})`;
- }
-
- return `${fieldIndent}.${methodName}(${formatPrimitive(value as never, resolved)})`;
- })
- .join("\n");
-
- return `${typeName}.builder()\n${fields}\n${fieldIndent}.build()`;
-};
-
-const requestBody = (operation: OperationObject): string => {
- const requestBodySchema =
- operation.requestBody?.content?.["application/json"]?.schema;
- if (!requestBodySchema) {
- return "";
- }
-
- const schema = resolveSchema(requestBodySchema);
- if (!schema || !schema.properties) {
- return "";
- }
-
- const example = getRequestBodyExample(operation);
-
- if (!example || typeof example !== "object") {
- return "";
- }
-
- const typeName = getSchemaTypeName(
- requestBodySchema,
- `${Case.pascal(operation.operationId!)}Body`,
- );
-
- return generateJavaBuilder(example, schema, typeName);
-};
-
-const formatArgument = (argument: string): string => {
- return `${INDENT}${indentMultiline(argument, INDENT)}`;
-};
-
-export const java = (operation: OperationObject): string => {
- const resource = Case.camel(operation.tag);
- const methodName = Case.camel(operation.operationId!);
-
- const requiredParams = operation.parameters?.filter((p) => p.required) || [];
- const paramArgs = requiredParams.map((param) => {
- const schema = param.schema ? resolveSchema(param.schema) : undefined;
- return formatPrimitive(getParameterExample(param), schema);
- });
-
- const bodyArg = requestBody(operation);
- const args = [...paramArgs];
-
- if (bodyArg) {
- args.push(bodyArg);
- }
-
- const formattedArgs =
- args.length > 0
- ? `\n${args.map((arg) => formatArgument(arg)).join(",\n")}\n`
- : "";
-
- return `import com.sumup.sdk.SumUpClient;
-
-SumUpClient client = SumUpClient.builder().build();
-
-var result = client.${resource}().${methodName}(${formattedArgs});`;
-};
diff --git a/src/lib/codesamples/node.ts b/src/lib/codesamples/node.ts
deleted file mode 100644
index 65bdbbea..00000000
--- a/src/lib/codesamples/node.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-import { resolveSchema } from "@lib/openapi";
-import { Case } from "change-case-all";
-import type { OpenAPIV3_1 } from "openapi-types";
-import type { OperationObject } from "src/types/openapi";
-import { getRequestBodyExample, getParameterExample } from "./util";
-
-/**
- * Generates TypeScript object literal code from an example object.
- */
-const generateTypeScriptObjectLiteral = (
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- example: any,
- schema: OpenAPIV3_1.SchemaObject,
- indent = "",
-): string => {
- if (example === null || example === undefined) {
- return "";
- }
-
- const properties = schema.properties || {};
-
- const fields = Object.entries(example)
- .map(([key, value]) => {
- const propSchema = properties[key];
-
- if (!propSchema) {
- return `${indent} ${key}: ${JSON.stringify(value)},`;
- }
-
- const resolved = resolveSchema(propSchema);
-
- // Handle nested objects
- if (
- typeof value === "object" &&
- value !== null &&
- !Array.isArray(value)
- ) {
- const nestedLiteral = generateTypeScriptObjectLiteral(
- value,
- resolved,
- indent + " ",
- );
- return `${indent} ${key}: ${nestedLiteral},`;
- }
-
- // Handle arrays
- if (Array.isArray(value)) {
- if (value.length === 0) {
- return `${indent} ${key}: [],`;
- }
-
- const firstItem = value[0];
- if (typeof firstItem === "object" && firstItem !== null) {
- const itemSchema =
- "items" in resolved && resolved.items
- ? resolveSchema(resolved.items)
- : {};
- const itemsLiteral = value
- .map((item) => {
- return `${indent} ${generateTypeScriptObjectLiteral(item, itemSchema as OpenAPIV3_1.SchemaObject, indent + " ")}`;
- })
- .join(",\n");
-
- return `${indent} ${key}: [\n${itemsLiteral},\n${indent} ],`;
- }
-
- return `${indent} ${key}: ${JSON.stringify(value)},`;
- }
-
- // Primitives
- return `${indent} ${key}: ${JSON.stringify(value)},`;
- })
- .join("\n");
-
- return `{\n${fields}\n${indent}}`;
-};
-
-const requestBody = (operation: OperationObject): string => {
- const requestBodySchema =
- operation.requestBody?.content?.["application/json"]?.schema;
- if (!requestBodySchema) {
- return "";
- }
-
- const schema = resolveSchema(requestBodySchema);
- if (!schema || !schema.properties) {
- return "";
- }
-
- const example = getRequestBodyExample(operation);
-
- if (!example || typeof example !== "object") {
- return "";
- }
-
- return generateTypeScriptObjectLiteral(example, schema);
-};
-
-export const node = (operation: OperationObject): string => {
- const resource = Case.camel(operation.tag);
- const method = Case.camel(
- operation["x-codegen"]?.method_name || operation.operationId!,
- );
-
- const body = requestBody(operation);
-
- // Extract required parameters and use their examples from referenced schemas if available
- const requiredParams = operation.parameters?.filter((p) => p.required) || [];
- const paramsString = requiredParams
- .map((param) => JSON.stringify(getParameterExample(param)))
- .join(", ");
-
- const paramsSection = paramsString
- ? `${paramsString}${body ? ", " : ""}`
- : "";
-
- const njs = `import SumUp from '@sumup/sdk';
-
-const client = new SumUp();
-
-const result = await client.${resource}.${method}(${paramsSection}${body});`;
-
- return njs;
-};
diff --git a/src/lib/codesamples/python.ts b/src/lib/codesamples/python.ts
deleted file mode 100644
index 684f556e..00000000
--- a/src/lib/codesamples/python.ts
+++ /dev/null
@@ -1,156 +0,0 @@
-import { resolveSchema } from "@lib/openapi";
-import { Case } from "change-case-all";
-import type { OpenAPIV3_1 } from "openapi-types";
-import type { OperationObject } from "src/types/openapi";
-import { getRequestBodyExample, getParameterExample } from "./util";
-
-/**
- * Generates Python class instantiation code from an example object.
- * Similar to Go struct initialization, uses Pydantic classes with keyword arguments.
- */
-const generatePythonClassInit = (
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- example: any,
- schema: OpenAPIV3_1.SchemaObject,
- indent = "",
-): string => {
- if (example === null || example === undefined) {
- return "";
- }
-
- const properties = schema.properties || {};
-
- const fields = Object.entries(example)
- .map(([key, value]) => {
- const propSchema = properties[key];
-
- if (!propSchema) {
- return `${indent} ${key}=${JSON.stringify(value)},`;
- }
-
- const resolved = resolveSchema(propSchema);
-
- // Handle nested objects
- if (
- typeof value === "object" &&
- value !== null &&
- !Array.isArray(value)
- ) {
- // Get the class name from $ref or use schema title/key
- let className = "";
- if ("$ref" in propSchema) {
- className = Case.pascal(propSchema.$ref.split("/").pop()!);
- } else if (resolved.title) {
- className = Case.pascal(resolved.title);
- } else {
- className = Case.pascal(key);
- }
-
- const nestedInit = generatePythonClassInit(
- value,
- resolved,
- indent + " ",
- );
- return `${indent} ${key}=${className}${nestedInit},`;
- }
-
- // Handle arrays
- if (Array.isArray(value)) {
- if (value.length === 0) {
- return `${indent} ${key}=[],`;
- }
-
- const firstItem = value[0];
- if (typeof firstItem === "object" && firstItem !== null) {
- // Array of objects
- let itemClassName = "";
- if (
- "items" in resolved &&
- resolved.items &&
- "$ref" in resolved.items
- ) {
- itemClassName = Case.pascal(resolved.items.$ref.split("/").pop()!);
- } else if (
- "items" in resolved &&
- resolved.items &&
- "title" in resolved.items &&
- resolved.items.title
- ) {
- itemClassName = Case.pascal(resolved.items.title);
- } else {
- itemClassName = Case.pascal(key);
- }
-
- const itemSchema =
- "items" in resolved && resolved.items
- ? resolveSchema(resolved.items)
- : {};
- const itemsInit = value
- .map((item) => {
- return `${indent} ${itemClassName}${generatePythonClassInit(item, itemSchema as OpenAPIV3_1.SchemaObject, indent + " ")}`;
- })
- .join(",\n");
-
- return `${indent} ${key}=[\n${itemsInit},\n${indent} ],`;
- }
-
- return `${indent} ${key}=${JSON.stringify(value)},`;
- }
-
- // Primitives
- return `${indent} ${key}=${JSON.stringify(value)},`;
- })
- .join("\n");
-
- return `(\n${fields}\n${indent})`;
-};
-
-const requestBody = (operation: OperationObject): string => {
- const requestBodySchema =
- operation.requestBody?.content?.["application/json"]?.schema;
- if (!requestBodySchema) {
- return "";
- }
-
- const schema = resolveSchema(requestBodySchema);
- if (!schema || !schema.properties) {
- return "";
- }
-
- const bodyClassName = `${Case.pascal(operation.operationId!)}Body`;
-
- const example = getRequestBodyExample(operation);
-
- if (!example || typeof example !== "object") {
- return "";
- }
-
- return `${bodyClassName}${generatePythonClassInit(example, schema)}`;
-};
-
-export const python = (operation: OperationObject): string => {
- const resource = Case.snake(operation.tag);
- const method = Case.snake(
- operation["x-codegen"]?.method_name || operation.operationId!,
- );
-
- const body = requestBody(operation);
-
- // Extract required parameters and use their examples from referenced schemas if available
- const requiredParams = operation.parameters?.filter((p) => p.required) || [];
- const paramsString = requiredParams
- .map((param) => JSON.stringify(getParameterExample(param)))
- .join(", ");
-
- const paramsSection = paramsString
- ? `${paramsString}${body ? ", " : ""}`
- : "";
-
- const njs = `from sumup import Sumup
-
-client = Sumup()
-
-result = client.${resource}.${method}(${paramsSection}${body})`;
-
- return njs;
-};
diff --git a/src/lib/codesamples/rust.ts b/src/lib/codesamples/rust.ts
deleted file mode 100644
index e7f13e65..00000000
--- a/src/lib/codesamples/rust.ts
+++ /dev/null
@@ -1,210 +0,0 @@
-import { resolveSchema } from "@lib/openapi";
-import { Case } from "change-case-all";
-import type { OpenAPIV3_1 } from "openapi-types";
-import type { OperationObject } from "src/types/openapi";
-import { getRequestBodyExample, getParameterExample } from "./util";
-
-/**
- * Generates Rust struct initialization code from an example object.
- * Uses Rust struct literal syntax with named fields.
- */
-const generateRustStructInit = (
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- example: any,
- schema: OpenAPIV3_1.SchemaObject,
- indent = "",
-): string => {
- if (example === null || example === undefined) {
- return "";
- }
-
- const properties = schema.properties || {};
-
- const fields = Object.entries(example)
- .map(([key, value]) => {
- const fieldName = Case.snake(key);
- const propSchema = properties[key];
-
- if (!propSchema) {
- return `${indent} ${fieldName}: ${JSON.stringify(value)},`;
- }
-
- const resolved = resolveSchema(propSchema);
-
- // Handle nested objects
- if (
- typeof value === "object" &&
- value !== null &&
- !Array.isArray(value)
- ) {
- // Get the struct name from $ref or use schema title/key
- let structName = "";
- if ("$ref" in propSchema) {
- structName = Case.pascal(propSchema.$ref.split("/").pop()!);
- } else if (resolved.title) {
- structName = Case.pascal(resolved.title);
- } else {
- structName = Case.pascal(key);
- }
-
- const nestedInit = generateRustStructInit(
- value,
- resolved,
- indent + " ",
- );
- return `${indent} ${fieldName}: sumup::${structName} ${nestedInit},`;
- }
-
- // Handle arrays
- if (Array.isArray(value)) {
- if (value.length === 0) {
- return `${indent} ${fieldName}: vec![],`;
- }
-
- const firstItem = value[0];
- if (typeof firstItem === "object" && firstItem !== null) {
- // Array of objects
- let itemStructName = "";
- if (
- "items" in resolved &&
- resolved.items &&
- "$ref" in resolved.items
- ) {
- itemStructName = Case.pascal(resolved.items.$ref.split("/").pop()!);
- } else if (
- "items" in resolved &&
- resolved.items &&
- "title" in resolved.items &&
- resolved.items.title
- ) {
- itemStructName = Case.pascal(resolved.items.title);
- } else {
- itemStructName = Case.pascal(key);
- }
-
- const itemSchema =
- "items" in resolved && resolved.items
- ? resolveSchema(resolved.items)
- : {};
- const itemsInit = value
- .map((item) => {
- return `${indent} ${itemStructName} ${generateRustStructInit(item, itemSchema as OpenAPIV3_1.SchemaObject, indent + " ")}`;
- })
- .join(",\n");
-
- return `${indent} ${fieldName}: vec![\n${itemsInit},\n${indent} ],`;
- }
-
- // Array of primitives
- const primitiveValues = value.map((v) => JSON.stringify(v)).join(", ");
- return `${indent} ${fieldName}: vec![${primitiveValues}],`;
- }
-
- // Primitives - handle strings with proper Rust syntax
- if (typeof value === "string") {
- if (resolved.format === "password") {
- return `${indent} ${fieldName}: crate::secret::Secret::from("${value}"),`;
- }
- return `${indent} ${fieldName}: "${value}".to_string(),`;
- }
-
- return `${indent} ${fieldName}: ${JSON.stringify(value)},`;
- })
- .join("\n");
-
- if (!fields) return "{}";
-
- return `{\n${fields}\n${indent}}`;
-};
-
-const requestBody = (operation: OperationObject): string => {
- const requestBodySchema =
- operation.requestBody?.content?.["application/json"]?.schema;
- if (!requestBodySchema) {
- return "";
- }
-
- const schema = resolveSchema(requestBodySchema);
- if (!schema || !schema.properties) {
- return "";
- }
-
- const bodyStructName = `${Case.pascal(operation.operationId!)}Body`;
-
- const example = getRequestBodyExample(operation);
-
- if (!example || typeof example !== "object") {
- return "";
- }
-
- return `sumup::${bodyStructName}${generateRustStructInit(example, schema)}`;
-};
-
-export const rust = (operation: OperationObject): string => {
- const resource = Case.snake(operation.tag);
- const method = Case.snake(
- operation["x-codegen"]?.method_name || operation.operationId!,
- );
-
- const body = requestBody(operation);
-
- // Separate path and query parameters
- const pathParams =
- operation.parameters?.filter((p) => p.in === "path" && p.required) || [];
- const queryParams =
- operation.parameters?.filter((p) => p.in === "query") || [];
-
- // Build the parameter list
- const paramsList: string[] = [];
-
- // Add path parameters first
- for (const param of pathParams) {
- const example = getParameterExample(param);
- const paramSchema = param.schema ? resolveSchema(param.schema) : {};
- if (typeof example === "string") {
- if (paramSchema.format === "password") {
- paramsList.push(`crate::secret::Secret::from("${example}")`);
- } else {
- paramsList.push(`"${example}"`);
- }
- } else {
- paramsList.push(`&${JSON.stringify(example)}`);
- }
- }
-
- // Add query parameters as a struct if any exist
- if (queryParams.length > 0) {
- const paramsStructName = `${Case.pascal(operation.operationId!)}Params`;
- const queryFields = queryParams
- .map((param) => {
- const fieldName = Case.snake(param.name);
- const example = getParameterExample(param);
- if (typeof example === "string") {
- return ` ${fieldName}: Some("${example}".to_string()),`;
- } else if (typeof example === "number") {
- return ` ${fieldName}: Some(${example}),`;
- } else if (typeof example === "boolean") {
- return ` ${fieldName}: Some(${example}),`;
- }
- return ` ${fieldName}: Some(${JSON.stringify(example)}),`;
- })
- .join("\n");
-
- paramsList.push(`sumup::${paramsStructName}{\n${queryFields}\n}`);
- }
-
- // Add body last
- if (body) {
- paramsList.push(`${body}`);
- }
-
- const paramsSection = paramsList.length > 0 ? paramsList.join(", ") : "";
-
- const rs = `use sumup::Client;
-
-let client = Client::default();
-
-let result = client.${resource}().${method}(${paramsSection}).await;`;
-
- return rs;
-};
diff --git a/src/lib/codesamples/util.ts b/src/lib/codesamples/util.ts
index 03041c60..3b1acd0e 100644
--- a/src/lib/codesamples/util.ts
+++ b/src/lib/codesamples/util.ts
@@ -1,4 +1,4 @@
-import { isRequestBody, resolveSchema, schemaToExample } from "@lib/openapi";
+import { resolveSchema, schemaToExample } from "@lib/openapi";
import type { OpenAPIV3_1 } from "openapi-types";
import type { OperationObject } from "src/types/openapi";
@@ -125,29 +125,6 @@ export const getRequestBodyExample = (operation: OperationObject): any => {
return filterRequiredFields(example, schema);
};
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export const bodyExample = (operation: OperationObject): any => {
- if (!isRequestBody(operation.requestBody)) {
- return undefined;
- }
-
- if (!("application/json" in operation.requestBody.content)) {
- return undefined;
- }
-
- if (operation.requestBody.content["application/json"].example) {
- return operation.requestBody.content["application/json"].example;
- }
-
- if (!operation.requestBody.content["application/json"].schema) {
- return undefined;
- }
-
- return schemaToExample(
- operation.requestBody.content["application/json"].schema!,
- );
-};
-
/**
* Gets the example value for a parameter.
* If the parameter schema is a reference, resolves it and uses its example.
diff --git a/src/pages/index.astro b/src/pages/index.astro
index b774a17e..29c7ae3a 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -117,8 +117,8 @@ const props = {
variant="navigation"
leadingComponent={Apps}
href="/tools/sdks/"
- label="Call APIs with a Server SDK"
- details="Use an official client across online and in-person integrations."
+ label="Call APIs with an SDK or CLI"
+ details="Use an official client library or work directly from your terminal."
/>