Skip to content

Commit 38632e4

Browse files
committed
Sync open source content 🐝 (from af7c36a9ec957336fb799151a4e5af3ae293831e)
1 parent e9d44b8 commit 38632e4

File tree

9 files changed

+961
-95
lines changed

9 files changed

+961
-95
lines changed

β€Ž_meta.global.tsxβ€Ž

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -435,14 +435,43 @@ const meta = {
435435
title: "Add webhooks to your SDKs",
436436
},
437437
code: {
438-
title: "Add Custom Code",
438+
title: "Modify SDK code",
439439
items: {
440+
"sdk-hooks": {
441+
title: "Hooks",
442+
},
443+
"custom-code": {
444+
title: "Custom code",
445+
items: {
446+
"custom-code": {
447+
title: "Overview",
448+
},
449+
"custom-code-best-practices": {
450+
title: "Best practices",
451+
},
452+
"custom-code-reference": {
453+
title: "Technical reference",
454+
},
455+
genignore: {
456+
title: "Ignoring files",
457+
},
458+
},
459+
},
440460
"code-regions": {
461+
title: "Code regions",
441462
items: {
442-
overview: {},
443-
python: {},
444-
typescript: {},
445-
java: {},
463+
overview: {
464+
title: "Custom code regions",
465+
},
466+
python: {
467+
title: "Python",
468+
},
469+
typescript: {
470+
title: "TypeScript",
471+
},
472+
java: {
473+
title: "Java",
474+
},
446475
},
447476
},
448477
},

β€Ždocs/sdks/customize/basics.mdxβ€Ž

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Overlays work by referencing and extending parts of the base OpenAPI document. T
3535

3636
## 2. Using x-speakeasy extensions
3737

38-
Proprietary Speakeasy extensions provide fine-tuned control over the SDK, enabling you to modify behaviors like retries, pagination, error handling, and other advanced SDK features.
38+
Proprietary Speakeasy extensions provide fine-tuned control over the SDK, enabling modification of behaviors such as retries, pagination, error handling, and other advanced SDK features.
3939

4040
Add Speakeasy extensions to the OpenAPI document.
4141

@@ -57,11 +57,36 @@ For a complete list of available options, refer to the [`gen.yaml` reference](/d
5757

5858
---
5959

60-
## SDK Dependencies
60+
## 4. Adding custom code to SDKs
6161

62-
Speakeasy-generated SDKs use carefully tested dependencies and tools to ensure reliability and compatibility. These dependencies are selected based on extensive testing and best practices for each language ecosystem.
62+
Speakeasy provides two approaches for adding custom code to generated SDKs:
6363

64-
### Dependency Version Management
64+
### SDK hooks
65+
66+
[SDK hooks](/docs/sdks/customize/code/sdk-hooks) enable custom logic at various points in the SDK request lifecycle, including SDK initialization, before requests, after successful responses, and after errors.
67+
68+
Best for:
69+
- Custom authentication and security schemes
70+
- Request/response transformations
71+
- Tracing and logging
72+
- HTTP client customization
73+
74+
### Custom code
75+
76+
[Custom code](/docs/sdks/customize/code/custom-code) allows custom changes anywhere in the generated SDK. Modifications are automatically preserved across regenerations using intelligent 3-way merging.
77+
78+
Best for:
79+
- Adding utility methods to models
80+
- Extending SDK initialization
81+
- Extending SDK methods (such as interactions hard to model with OpenAPI)
82+
83+
---
84+
85+
## SDK dependencies
86+
87+
Speakeasy-generated SDKs use dependencies and tools selected based on extensive testing and best practices for each language ecosystem.
88+
89+
### Dependency version management
6590

6691
Speakeasy does not provide an out-of-the-box way to change the versions of dependencies that are automatically added to generated SDKs. This design decision ensures that:
6792

β€Ždocs/sdks/customize/code/code-regions/overview.mdxβ€Ž

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,11 @@ import { Callout } from "@/mdx/components";
77

88
# Custom code regions
99

10-
<Callout title="Availability" type="info">
11-
Custom code regions are only available for [Enterprise users](/pricing).
12-
Custom code regions must be enabled in `settings/billing` under the account.
10+
<Callout title="New feature" type="info">
11+
Looking for more flexibility? Check out [Custom code](/docs/sdks/customize/code/custom-code/custom-code) - a feature that allows custom changes anywhere in the SDK, not just in predefined regions.
1312
</Callout>
1413

15-
Generally, the Speakeasy code generator "owns" the files it generates. If
16-
modifications are made to them, then the next code generation run will overwrite
17-
all edits. One way to persist modifications to generated files is
14+
Generally, the Speakeasy code generator "owns" the files it generates. Modifying these files causes the next generation run to overwrite all edits. One way to persist modifications to generated files is
1815
to add them to `.genignore`, but this has a significant drawback: those files
1916
will stop receiving updates during generation, and thus risk build failures in
2017
the future.
@@ -26,14 +23,19 @@ functionality to SDKs.
2623

2724
## Syntax
2825

29-
Custom code regions are defined by adding a start and end comments to prescribed
26+
Custom code regions are defined by adding start and end comments to prescribed
3027
sections of a generated file. The comments follow Visual Studio Code's format
3128
for [creating code folds](https://code.visualstudio.com/docs/editor/codebasics#_folding).
3229

3330
## Language support
3431

3532
Custom code regions are currently supported in the following languages:
3633

37-
- [Java](/docs/customize/code/code-regions/java)
38-
- [Python](/docs/customize/code/code-regions/python)
39-
- [TypeScript](/docs/customize/code/code-regions/typescript)
34+
- [Java](/docs/sdks/customize/code/code-regions/java)
35+
- [Python](/docs/sdks/customize/code/code-regions/python)
36+
- [TypeScript](/docs/sdks/customize/code/code-regions/typescript)
37+
38+
<Callout title="Availability" type="tip">
39+
Custom code regions are only available for [Enterprise users](/pricing).
40+
Custom code regions must be enabled in `settings/billing` under the account.
41+
</Callout>
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
---
2+
title: Custom code best practices
3+
description: "Best practices and tips for using custom code effectively in team environments."
4+
---
5+
6+
import { Callout } from "@/mdx/components";
7+
8+
# Custom code best practices
9+
10+
This guide covers best practices for using custom code effectively, avoiding common pitfalls, and working smoothly in team environments.
11+
12+
## When to use custom code
13+
14+
### Good use cases
15+
16+
Custom code works best for:
17+
18+
- **Adding utility methods** to models or SDK classes
19+
- **Extending initialization** with custom authentication or middleware
20+
- **Modifying configuration files** like package.json or pyproject.toml
21+
- **Adding business logic** specific to the domain
22+
- **Performance optimizations** that require deep changes
23+
- **Integration code** for internal systems
24+
25+
### When to consider alternatives
26+
27+
Consider other approaches when:
28+
29+
- **OpenAPI can solve it**: Many customizations can be handled via OpenAPI extensions
30+
- **Hooks suffice**: [SDK hooks](/docs/sdks/customize/code/sdk-hooks) might provide enough flexibility if you want to simply alter or act on the request or response. They are also useful for custom authentication setups
31+
32+
## Avoiding conflicts
33+
34+
### Structure changes to minimize conflicts
35+
36+
**Delegate logic to separate files**
37+
38+
Keep changes in generated files minimal to reduce merge conflicts.
39+
40+
```typescript
41+
// ❌ Avoid: Writing complex logic directly in generated files
42+
export class PaymentSDK {
43+
async createPayment(data: PaymentRequest): Promise<Payment> {
44+
// Generated code...
45+
46+
// 50 lines of custom validation logic mixed in...
47+
if (!data.amount || data.amount < 0) {
48+
// ...complex validation...
49+
}
50+
51+
// More generated code...
52+
}
53+
}
54+
55+
// βœ… Better: Import and call external logic
56+
import { validatePayment } from "./custom/validator"; // Only 1 line added
57+
58+
export class PaymentSDK {
59+
async createPayment(data: PaymentRequest): Promise<Payment> {
60+
validatePayment(data); // Only 1 line added
61+
// Generated code continues unchanged...
62+
}
63+
}
64+
```
65+
66+
**Add methods, do not modify existing ones**
67+
```typescript
68+
// ❌ Avoid: Modifying generated methods
69+
class User {
70+
// This method is generated
71+
getName(): string {
72+
// Changed the implementation
73+
return this.firstName + " " + this.lastName;
74+
}
75+
}
76+
77+
// βœ… Better: Add new methods
78+
class User {
79+
// Generated method untouched
80+
getName(): string {
81+
return this.name;
82+
}
83+
84+
// Custom method addition
85+
getFullName(): string {
86+
return this.firstName + " " + this.lastName;
87+
}
88+
}
89+
```
90+
91+
## Team workflows
92+
93+
### Communicating changes
94+
95+
**Document customizations**
96+
Create a `CUSTOMIZATIONS.md` file in the SDK:
97+
98+
```markdown filename="CUSTOMIZATIONS.md"
99+
# SDK Customizations
100+
101+
This SDK has custom code enabled. The following customizations have been added:
102+
103+
## Utility Methods
104+
- `Payment.toInvoiceItem()` - Converts payments to invoice format
105+
- `User.getFullName()` - Returns formatted full name
106+
107+
## Custom Dependencies
108+
- `aws-sdk` - For S3 upload functionality
109+
- `redis` - For caching API responses
110+
111+
## Modified Files
112+
- `src/models/payment.ts` - Added utility methods
113+
- `package.json` - Added custom dependencies and scripts
114+
```
115+
116+
**Use clear commit messages**
117+
```bash
118+
# When adding customizations
119+
git commit -m "feat(sdk): add payment utility methods for invoice conversion"
120+
121+
# When resolving conflicts
122+
git commit -m "fix(sdk): resolve generation conflicts in payment model"
123+
```
124+
125+
## Troubleshooting tips
126+
127+
### Common patterns to avoid
128+
129+
**Do not remove generated headers**
130+
```typescript
131+
// ❌ Do not remove these
132+
// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
133+
// @generated-id: a1b2c3d4e5f6
134+
135+
// βœ… Keep them for move detection to work
136+
```
137+
138+
**Do not copy files with IDs**
139+
```bash
140+
# ❌ Copying creates duplicate IDs
141+
cp src/models/user.ts src/models/user-v2.ts
142+
143+
# βœ… Either move or create new file
144+
mv src/models/user.ts src/models/user-v2.ts
145+
# or create fresh without the @generated-id header
146+
```
147+
148+
### Recovery procedures
149+
150+
**Reset a single file**
151+
```bash
152+
# Remove custom changes from one file
153+
git checkout HEAD -- src/models/payment.ts
154+
155+
# Re-run generation using the same pristine snapshot (no new snapshot is created)
156+
speakeasy run --skip-versioning
157+
```
158+
159+
**Reset everything**
160+
```bash
161+
# Disable custom code
162+
# Edit .speakeasy/gen.yaml: enabled: false
163+
164+
# Remove all generated files
165+
find . -name "*.gen.*" -delete # Adjust pattern for the SDK
166+
167+
# Regenerate fresh
168+
speakeasy run
169+
```
170+
171+
**Fix "duplicate ID" warnings**
172+
1. Find files with duplicate IDs
173+
2. Remove `@generated-id` line from copied files
174+
3. Let next generation assign new IDs
175+
176+
## Summary checklist
177+
178+
<Callout title="Quick reference" type="info">
179+
βœ“ Enable custom code before reorganizing files. Move detection is file-specific, not folder-specific
180+
βœ“ Document customizations for team members
181+
βœ“ Do not remove @generated-id headers
182+
βœ“ Commit custom edits independently of generator changes for clarity
183+
</Callout>

0 commit comments

Comments
Β (0)