@intentsolutionsio/vercel-pack 1.0.0 → 1.0.3

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.
Files changed (124) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +67 -44
  3. package/package.json +4 -4
  4. package/skills/vercel-advanced-troubleshooting/SKILL.md +185 -195
  5. package/skills/vercel-advanced-troubleshooting/references/errors.md +11 -0
  6. package/skills/vercel-advanced-troubleshooting/references/evidence-collection-framework.md +34 -0
  7. package/skills/vercel-advanced-troubleshooting/references/examples.md +11 -0
  8. package/skills/vercel-advanced-troubleshooting/references/systematic-isolation.md +56 -0
  9. package/skills/vercel-advanced-troubleshooting/references/timing-analysis.md +35 -0
  10. package/skills/vercel-architecture-variants/SKILL.md +227 -216
  11. package/skills/vercel-architecture-variants/references/errors.md +11 -0
  12. package/skills/vercel-architecture-variants/references/examples.md +12 -0
  13. package/skills/vercel-architecture-variants/references/variant-a-monolith-(simple).md +44 -0
  14. package/skills/vercel-architecture-variants/references/variant-b-service-layer-(moderate).md +72 -0
  15. package/skills/vercel-architecture-variants/references/variant-c-microservice-(complex).md +81 -0
  16. package/skills/vercel-ci-integration/SKILL.md +183 -73
  17. package/skills/vercel-ci-integration/references/errors.md +10 -0
  18. package/skills/vercel-ci-integration/references/examples.md +36 -0
  19. package/skills/vercel-ci-integration/references/implementation.md +54 -0
  20. package/skills/vercel-common-errors/SKILL.md +164 -60
  21. package/skills/vercel-common-errors/references/errors.md +53 -0
  22. package/skills/vercel-common-errors/references/examples.md +23 -0
  23. package/skills/vercel-cost-tuning/SKILL.md +158 -145
  24. package/skills/vercel-cost-tuning/references/cost-estimation.md +34 -0
  25. package/skills/vercel-cost-tuning/references/cost-reduction-strategies.md +40 -0
  26. package/skills/vercel-cost-tuning/references/errors.md +11 -0
  27. package/skills/vercel-cost-tuning/references/examples.md +15 -0
  28. package/skills/vercel-data-handling/SKILL.md +202 -155
  29. package/skills/vercel-data-handling/references/errors.md +11 -0
  30. package/skills/vercel-data-handling/references/examples.md +27 -0
  31. package/skills/vercel-data-handling/references/implementation.md +223 -0
  32. package/skills/vercel-debug-bundle/SKILL.md +163 -67
  33. package/skills/vercel-debug-bundle/references/errors.md +12 -0
  34. package/skills/vercel-debug-bundle/references/examples.md +24 -0
  35. package/skills/vercel-debug-bundle/references/implementation.md +54 -0
  36. package/skills/vercel-deploy-integration/SKILL.md +163 -156
  37. package/skills/vercel-deploy-integration/references/errors.md +11 -0
  38. package/skills/vercel-deploy-integration/references/examples.md +21 -0
  39. package/skills/vercel-deploy-integration/references/google-cloud-run.md +36 -0
  40. package/skills/vercel-deploy-integration/references/vercel-deployment.md +35 -0
  41. package/skills/vercel-deploy-preview/SKILL.md +164 -39
  42. package/skills/vercel-edge-functions/SKILL.md +185 -37
  43. package/skills/vercel-enterprise-rbac/SKILL.md +185 -170
  44. package/skills/vercel-enterprise-rbac/references/errors.md +11 -0
  45. package/skills/vercel-enterprise-rbac/references/examples.md +12 -0
  46. package/skills/vercel-enterprise-rbac/references/role-implementation.md +33 -0
  47. package/skills/vercel-enterprise-rbac/references/sso-integration.md +35 -0
  48. package/skills/vercel-hello-world/SKILL.md +141 -55
  49. package/skills/vercel-incident-runbook/SKILL.md +186 -138
  50. package/skills/vercel-incident-runbook/references/errors.md +11 -0
  51. package/skills/vercel-incident-runbook/references/examples.md +10 -0
  52. package/skills/vercel-incident-runbook/references/immediate-actions-by-error-type.md +41 -0
  53. package/skills/vercel-install-auth/SKILL.md +130 -53
  54. package/skills/vercel-known-pitfalls/SKILL.md +235 -233
  55. package/skills/vercel-known-pitfalls/references/errors.md +11 -0
  56. package/skills/vercel-known-pitfalls/references/examples.md +12 -0
  57. package/skills/vercel-load-scale/SKILL.md +197 -204
  58. package/skills/vercel-load-scale/references/capacity-planning.md +47 -0
  59. package/skills/vercel-load-scale/references/errors.md +11 -0
  60. package/skills/vercel-load-scale/references/examples.md +26 -0
  61. package/skills/vercel-load-scale/references/load-testing-with-k6.md +59 -0
  62. package/skills/vercel-load-scale/references/scaling-patterns.md +65 -0
  63. package/skills/vercel-local-dev-loop/SKILL.md +159 -71
  64. package/skills/vercel-local-dev-loop/references/errors.md +11 -0
  65. package/skills/vercel-local-dev-loop/references/examples.md +21 -0
  66. package/skills/vercel-local-dev-loop/references/implementation.md +60 -0
  67. package/skills/vercel-migration-deep-dive/SKILL.md +202 -187
  68. package/skills/vercel-migration-deep-dive/references/errors.md +11 -0
  69. package/skills/vercel-migration-deep-dive/references/examples.md +12 -0
  70. package/skills/vercel-migration-deep-dive/references/implementation-plan.md +80 -0
  71. package/skills/vercel-migration-deep-dive/references/pre-migration-assessment.md +39 -0
  72. package/skills/vercel-multi-env-setup/SKILL.md +167 -164
  73. package/skills/vercel-multi-env-setup/references/configuration-structure.md +59 -0
  74. package/skills/vercel-multi-env-setup/references/errors.md +11 -0
  75. package/skills/vercel-multi-env-setup/references/examples.md +11 -0
  76. package/skills/vercel-observability/SKILL.md +205 -195
  77. package/skills/vercel-observability/references/alert-configuration.md +40 -0
  78. package/skills/vercel-observability/references/errors.md +11 -0
  79. package/skills/vercel-observability/references/examples.md +13 -0
  80. package/skills/vercel-observability/references/metrics-collection.md +65 -0
  81. package/skills/vercel-performance-tuning/SKILL.md +212 -156
  82. package/skills/vercel-performance-tuning/references/caching-strategy.md +49 -0
  83. package/skills/vercel-performance-tuning/references/errors.md +11 -0
  84. package/skills/vercel-performance-tuning/references/examples.md +13 -0
  85. package/skills/vercel-policy-guardrails/SKILL.md +276 -193
  86. package/skills/vercel-policy-guardrails/references/errors.md +11 -0
  87. package/skills/vercel-policy-guardrails/references/eslint-rules.md +46 -0
  88. package/skills/vercel-policy-guardrails/references/examples.md +10 -0
  89. package/skills/vercel-prod-checklist/SKILL.md +219 -94
  90. package/skills/vercel-prod-checklist/references/errors.md +11 -0
  91. package/skills/vercel-prod-checklist/references/examples.md +25 -0
  92. package/skills/vercel-prod-checklist/references/implementation.md +60 -0
  93. package/skills/vercel-rate-limits/SKILL.md +187 -100
  94. package/skills/vercel-rate-limits/references/errors.md +11 -0
  95. package/skills/vercel-rate-limits/references/examples.md +46 -0
  96. package/skills/vercel-rate-limits/references/implementation.md +66 -0
  97. package/skills/vercel-reference-architecture/SKILL.md +226 -180
  98. package/skills/vercel-reference-architecture/references/errors.md +11 -0
  99. package/skills/vercel-reference-architecture/references/examples.md +13 -0
  100. package/skills/vercel-reference-architecture/references/key-components.md +65 -0
  101. package/skills/vercel-reference-architecture/references/project-structure.md +40 -0
  102. package/skills/vercel-reliability-patterns/SKILL.md +272 -211
  103. package/skills/vercel-reliability-patterns/references/circuit-breaker.md +36 -0
  104. package/skills/vercel-reliability-patterns/references/dead-letter-queue.md +48 -0
  105. package/skills/vercel-reliability-patterns/references/errors.md +11 -0
  106. package/skills/vercel-reliability-patterns/references/examples.md +11 -0
  107. package/skills/vercel-reliability-patterns/references/idempotency-keys.md +36 -0
  108. package/skills/vercel-sdk-patterns/SKILL.md +264 -92
  109. package/skills/vercel-sdk-patterns/references/errors.md +11 -0
  110. package/skills/vercel-sdk-patterns/references/examples.md +45 -0
  111. package/skills/vercel-sdk-patterns/references/implementation.md +67 -0
  112. package/skills/vercel-security-basics/SKILL.md +186 -96
  113. package/skills/vercel-security-basics/references/errors.md +10 -0
  114. package/skills/vercel-security-basics/references/examples.md +70 -0
  115. package/skills/vercel-security-basics/references/implementation.md +39 -0
  116. package/skills/vercel-upgrade-migration/SKILL.md +167 -67
  117. package/skills/vercel-upgrade-migration/references/errors.md +10 -0
  118. package/skills/vercel-upgrade-migration/references/examples.md +51 -0
  119. package/skills/vercel-upgrade-migration/references/implementation.md +29 -0
  120. package/skills/vercel-webhooks-events/SKILL.md +208 -132
  121. package/skills/vercel-webhooks-events/references/errors.md +11 -0
  122. package/skills/vercel-webhooks-events/references/event-handler-pattern.md +37 -0
  123. package/skills/vercel-webhooks-events/references/examples.md +16 -0
  124. package/skills/vercel-webhooks-events/references/signature-verification.md +33 -0
@@ -0,0 +1,36 @@
1
+ # Idempotency Keys
2
+
3
+ ## Idempotency Keys
4
+
5
+ ```typescript
6
+ import { v4 as uuidv4 } from 'uuid';
7
+ import crypto from 'crypto';
8
+
9
+ // Generate deterministic idempotency key from input
10
+ function generateIdempotencyKey(
11
+ operation: string,
12
+ params: Record<string, any>
13
+ ): string {
14
+ const data = JSON.stringify({ operation, params });
15
+ return crypto.createHash('sha256').update(data).digest('hex');
16
+ }
17
+
18
+ // Or use random key with storage
19
+ class IdempotencyManager {
20
+ private store: Map<string, { key: string; expiresAt: Date }> = new Map();
21
+
22
+ getOrCreate(operationId: string): string {
23
+ const existing = this.store.get(operationId);
24
+ if (existing && existing.expiresAt > new Date()) {
25
+ return existing.key;
26
+ }
27
+
28
+ const key = uuidv4();
29
+ this.store.set(operationId, {
30
+ key,
31
+ expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000),
32
+ });
33
+ return key;
34
+ }
35
+ }
36
+ ```
@@ -1,147 +1,319 @@
1
1
  ---
2
2
  name: vercel-sdk-patterns
3
- description: |
4
- Apply production-ready Vercel SDK patterns for TypeScript and Python.
5
- Use when implementing Vercel integrations, refactoring SDK usage,
6
- or establishing team coding standards for Vercel.
7
- Trigger with phrases like "vercel SDK patterns", "vercel best practices",
8
- "vercel code patterns", "idiomatic vercel".
3
+ description: 'Production-ready Vercel REST API patterns with typed fetch wrappers
4
+ and error handling.
5
+
6
+ Use when integrating with the Vercel API programmatically, building deployment tools,
7
+
8
+ or establishing team coding standards for Vercel API calls.
9
+
10
+ Trigger with phrases like "vercel SDK patterns", "vercel API wrapper",
11
+
12
+ "vercel REST API client", "vercel best practices", "idiomatic vercel API".
13
+
14
+ '
9
15
  allowed-tools: Read, Write, Edit
10
16
  version: 1.0.0
11
17
  license: MIT
12
18
  author: Jeremy Longshore <jeremy@intentsolutions.io>
19
+ tags:
20
+ - saas
21
+ - vercel
22
+ - api
23
+ - typescript
24
+ - patterns
25
+ compatibility: Designed for Claude Code, also compatible with Codex and OpenClaw
13
26
  ---
14
-
15
27
  # Vercel SDK Patterns
16
28
 
17
29
  ## Overview
18
- Production-ready patterns for Vercel SDK usage in TypeScript and Python.
30
+
31
+ Build a typed, production-ready wrapper around the Vercel REST API (`api.vercel.com`). Covers authentication, pagination, error handling, retry logic, and common endpoint patterns for deployments, projects, and environment variables.
19
32
 
20
33
  ## Prerequisites
34
+
21
35
  - Completed `vercel-install-auth` setup
22
- - Familiarity with async/await patterns
23
- - Understanding of error handling best practices
36
+ - TypeScript project with `strict` mode enabled
37
+ - Vercel access token with appropriate scope
24
38
 
25
39
  ## Instructions
26
40
 
27
- ### Step 1: Implement Singleton Pattern (Recommended)
41
+ ### Step 1: Create Typed API Client
42
+
28
43
  ```typescript
29
- // src/vercel/client.ts
30
- import { VercelClient } from 'vercel';
44
+ // lib/vercel-client.ts
45
+ interface VercelClientConfig {
46
+ token: string;
47
+ teamId?: string;
48
+ baseUrl?: string;
49
+ }
50
+
51
+ interface VercelError {
52
+ error: { code: string; message: string };
53
+ }
54
+
55
+ class VercelClient {
56
+ private token: string;
57
+ private teamId?: string;
58
+ private baseUrl: string;
31
59
 
32
- let instance: VercelClient | null = null;
60
+ constructor(config: VercelClientConfig) {
61
+ this.token = config.token;
62
+ this.teamId = config.teamId;
63
+ this.baseUrl = config.baseUrl ?? 'https://api.vercel.com';
64
+ }
65
+
66
+ private async request<T>(
67
+ method: string,
68
+ path: string,
69
+ body?: unknown
70
+ ): Promise<T> {
71
+ const url = new URL(path, this.baseUrl);
72
+ if (this.teamId) url.searchParams.set('teamId', this.teamId);
33
73
 
34
- export function getVercelClient(): VercelClient {
35
- if (!instance) {
36
- instance = new VercelClient({
37
- apiKey: process.env.VERCEL_API_KEY!,
38
- // Additional options
74
+ const res = await fetch(url.toString(), {
75
+ method,
76
+ headers: {
77
+ Authorization: `Bearer ${this.token}`,
78
+ 'Content-Type': 'application/json',
79
+ },
80
+ body: body ? JSON.stringify(body) : undefined,
39
81
  });
82
+
83
+ if (!res.ok) {
84
+ const err: VercelError = await res.json();
85
+ throw new VercelApiError(res.status, err.error.code, err.error.message);
86
+ }
87
+
88
+ // 204 No Content
89
+ if (res.status === 204) return undefined as T;
90
+ return res.json() as Promise<T>;
91
+ }
92
+
93
+ // --- Projects ---
94
+ async listProjects(limit = 20) {
95
+ return this.request<{ projects: VercelProject[] }>(
96
+ 'GET', `/v9/projects?limit=${limit}`
97
+ );
98
+ }
99
+
100
+ async getProject(idOrName: string) {
101
+ return this.request<VercelProject>('GET', `/v9/projects/${idOrName}`);
102
+ }
103
+
104
+ // --- Deployments ---
105
+ async listDeployments(projectId?: string, limit = 20) {
106
+ const params = new URLSearchParams({ limit: String(limit) });
107
+ if (projectId) params.set('projectId', projectId);
108
+ return this.request<{ deployments: VercelDeployment[] }>(
109
+ 'GET', `/v6/deployments?${params}`
110
+ );
111
+ }
112
+
113
+ async getDeployment(idOrUrl: string) {
114
+ return this.request<VercelDeployment>(
115
+ 'GET', `/v13/deployments/${idOrUrl}`
116
+ );
117
+ }
118
+
119
+ // --- Environment Variables ---
120
+ async listEnvVars(projectId: string) {
121
+ return this.request<{ envs: VercelEnvVar[] }>(
122
+ 'GET', `/v9/projects/${projectId}/env`
123
+ );
124
+ }
125
+
126
+ async createEnvVar(projectId: string, envVar: CreateEnvVarInput) {
127
+ return this.request<VercelEnvVar>(
128
+ 'POST', `/v9/projects/${projectId}/env`, envVar
129
+ );
130
+ }
131
+
132
+ // --- Domains ---
133
+ async listDomains(projectId: string) {
134
+ return this.request<{ domains: VercelDomain[] }>(
135
+ 'GET', `/v9/projects/${projectId}/domains`
136
+ );
137
+ }
138
+
139
+ async addDomain(projectId: string, domain: string) {
140
+ return this.request<VercelDomain>(
141
+ 'POST', `/v9/projects/${projectId}/domains`, { name: domain }
142
+ );
40
143
  }
41
- return instance;
42
144
  }
43
145
  ```
44
146
 
45
- ### Step 2: Add Error Handling Wrapper
147
+ ### Step 2: Define Types
148
+
46
149
  ```typescript
47
- import { VercelError } from 'vercel';
48
-
49
- async function safeVercelCall<T>(
50
- operation: () => Promise<T>
51
- ): Promise<{ data: T | null; error: Error | null }> {
52
- try {
53
- const data = await operation();
54
- return { data, error: null };
55
- } catch (err) {
56
- if (err instanceof VercelError) {
57
- console.error({
58
- code: err.code,
59
- message: err.message,
60
- });
61
- }
62
- return { data: null, error: err as Error };
150
+ // lib/vercel-types.ts
151
+ interface VercelProject {
152
+ id: string;
153
+ name: string;
154
+ framework: string | null;
155
+ latestDeployments: VercelDeployment[];
156
+ targets: Record<string, VercelDeployment>;
157
+ createdAt: number;
158
+ updatedAt: number;
159
+ }
160
+
161
+ interface VercelDeployment {
162
+ uid: string;
163
+ name: string;
164
+ url: string;
165
+ state: 'BUILDING' | 'ERROR' | 'INITIALIZING' | 'QUEUED' | 'READY' | 'CANCELED';
166
+ target: 'production' | 'preview' | null;
167
+ createdAt: number;
168
+ buildingAt: number;
169
+ ready: number;
170
+ meta: Record<string, string>;
171
+ }
172
+
173
+ interface VercelEnvVar {
174
+ id: string;
175
+ key: string;
176
+ value: string;
177
+ type: 'system' | 'encrypted' | 'plain' | 'sensitive';
178
+ target: ('production' | 'preview' | 'development')[];
179
+ createdAt: number;
180
+ updatedAt: number;
181
+ }
182
+
183
+ interface CreateEnvVarInput {
184
+ key: string;
185
+ value: string;
186
+ type: 'encrypted' | 'plain' | 'sensitive';
187
+ target: ('production' | 'preview' | 'development')[];
188
+ }
189
+
190
+ interface VercelDomain {
191
+ name: string;
192
+ verified: boolean;
193
+ redirect: string | null;
194
+ gitBranch: string | null;
195
+ createdAt: number;
196
+ updatedAt: number;
197
+ }
198
+ ```
199
+
200
+ ### Step 3: Custom Error Class
201
+
202
+ ```typescript
203
+ // lib/vercel-errors.ts
204
+ class VercelApiError extends Error {
205
+ constructor(
206
+ public status: number,
207
+ public code: string,
208
+ message: string
209
+ ) {
210
+ super(`Vercel API ${status}: [${code}] ${message}`);
211
+ this.name = 'VercelApiError';
63
212
  }
213
+
214
+ get isRateLimit(): boolean { return this.status === 429; }
215
+ get isNotFound(): boolean { return this.status === 404; }
216
+ get isUnauthorized(): boolean { return this.status === 401 || this.status === 403; }
64
217
  }
65
218
  ```
66
219
 
67
- ### Step 3: Implement Retry Logic
220
+ ### Step 4: Retry with Exponential Backoff
221
+
68
222
  ```typescript
223
+ // lib/vercel-retry.ts
69
224
  async function withRetry<T>(
70
- operation: () => Promise<T>,
225
+ fn: () => Promise<T>,
71
226
  maxRetries = 3,
72
- backoffMs = 1000
227
+ baseDelayMs = 1000
73
228
  ): Promise<T> {
74
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
229
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
75
230
  try {
76
- return await operation();
231
+ return await fn();
77
232
  } catch (err) {
78
- if (attempt === maxRetries) throw err;
79
- const delay = backoffMs * Math.pow(2, attempt - 1);
80
- await new Promise(r => setTimeout(r, delay));
233
+ if (err instanceof VercelApiError && err.isRateLimit && attempt < maxRetries) {
234
+ const delay = baseDelayMs * Math.pow(2, attempt) + Math.random() * 500;
235
+ console.warn(`Rate limited. Retrying in ${Math.round(delay)}ms...`);
236
+ await new Promise(r => setTimeout(r, delay));
237
+ continue;
238
+ }
239
+ throw err;
81
240
  }
82
241
  }
83
242
  throw new Error('Unreachable');
84
243
  }
244
+
245
+ // Usage:
246
+ // const projects = await withRetry(() => client.listProjects());
85
247
  ```
86
248
 
87
- ## Output
88
- - Type-safe client singleton
89
- - Robust error handling with structured logging
90
- - Automatic retry with exponential backoff
91
- - Runtime validation for API responses
249
+ ### Step 5: Paginated Fetching
92
250
 
93
- ## Error Handling
94
- | Pattern | Use Case | Benefit |
95
- |---------|----------|---------|
96
- | Safe wrapper | All API calls | Prevents uncaught exceptions |
97
- | Retry logic | Transient failures | Improves reliability |
98
- | Type guards | Response validation | Catches API changes |
99
- | Logging | All operations | Debugging and monitoring |
251
+ ```typescript
252
+ // lib/vercel-pagination.ts
253
+ async function* paginateDeployments(
254
+ client: VercelClient,
255
+ projectId: string,
256
+ pageSize = 100
257
+ ): AsyncGenerator<VercelDeployment[]> {
258
+ let until: number | undefined;
100
259
 
101
- ## Examples
260
+ while (true) {
261
+ const params = new URLSearchParams({ limit: String(pageSize) });
262
+ if (until) params.set('until', String(until));
263
+ if (projectId) params.set('projectId', projectId);
102
264
 
103
- ### Factory Pattern (Multi-tenant)
104
- ```typescript
105
- const clients = new Map<string, VercelClient>();
265
+ const { deployments } = await client.listDeployments(projectId, pageSize);
266
+ if (deployments.length === 0) break;
106
267
 
107
- export function getClientForTenant(tenantId: string): VercelClient {
108
- if (!clients.has(tenantId)) {
109
- const apiKey = getTenantApiKey(tenantId);
110
- clients.set(tenantId, new VercelClient({ apiKey }));
268
+ yield deployments;
269
+ until = deployments[deployments.length - 1].createdAt;
270
+ if (deployments.length < pageSize) break;
111
271
  }
112
- return clients.get(tenantId)!;
113
272
  }
114
273
  ```
115
274
 
116
- ### Python Context Manager
117
- ```python
118
- from contextlib import asynccontextmanager
119
- from None import VercelClient
120
-
121
- @asynccontextmanager
122
- async def get_vercel_client():
123
- client = VercelClient()
124
- try:
125
- yield client
126
- finally:
127
- await client.close()
128
- ```
275
+ ## API Endpoint Quick Reference
129
276
 
130
- ### Zod Validation
131
- ```typescript
132
- import { z } from 'zod';
277
+ | Operation | Method | Endpoint |
278
+ |-----------|--------|----------|
279
+ | List projects | GET | `/v9/projects` |
280
+ | Get project | GET | `/v9/projects/{idOrName}` |
281
+ | Delete project | DELETE | `/v9/projects/{idOrName}` |
282
+ | List deployments | GET | `/v6/deployments` |
283
+ | Create deployment | POST | `/v13/deployments` |
284
+ | Get deployment | GET | `/v13/deployments/{id}` |
285
+ | Delete deployment | DELETE | `/v13/deployments/{id}` |
286
+ | List env vars | GET | `/v9/projects/{id}/env` |
287
+ | Create env var | POST | `/v9/projects/{id}/env` |
288
+ | Edit env var | PATCH | `/v9/projects/{id}/env/{envId}` |
289
+ | Delete env var | DELETE | `/v9/projects/{id}/env/{envId}` |
290
+ | Add domain | POST | `/v9/projects/{id}/domains` |
291
+ | Verify domain | POST | `/v9/projects/{id}/domains/{domain}/verify` |
292
+ | List teams | GET | `/v2/teams` |
133
293
 
134
- const vercelResponseSchema = z.object({
135
- id: z.string(),
136
- status: z.enum(['active', 'inactive']),
137
- createdAt: z.string().datetime(),
138
- });
139
- ```
294
+ ## Output
295
+
296
+ - Type-safe Vercel API client with full TypeScript coverage
297
+ - Custom error class with semantic helpers (isRateLimit, isNotFound)
298
+ - Automatic retry with exponential backoff for 429 responses
299
+ - Paginated data fetching for large result sets
300
+
301
+ ## Error Handling
302
+
303
+ | Error | Status | Solution |
304
+ |-------|--------|----------|
305
+ | `forbidden` | 403 | Token lacks scope — regenerate with correct permissions |
306
+ | `not_found` | 404 | Check project/deployment ID is correct |
307
+ | `rate_limited` | 429 | Use `withRetry()` wrapper — waits and retries automatically |
308
+ | `team_not_found` | 404 | Verify `teamId` parameter matches your team |
309
+ | `bad_request` | 400 | Validate request body matches API schema |
140
310
 
141
311
  ## Resources
142
- - [Vercel SDK Reference](https://vercel.com/docs/sdk)
143
- - [Vercel API Types](https://vercel.com/docs/types)
144
- - [Zod Documentation](https://zod.dev/)
312
+
313
+ - [Vercel REST API Reference](https://vercel.com/docs/rest-api)
314
+ - [Vercel REST API Endpoints](https://vercel.com/docs/rest-api/reference)
315
+ - [Authentication](https://vercel.com/docs/rest-api#creating-an-access-token)
145
316
 
146
317
  ## Next Steps
147
- Apply patterns in `vercel-core-workflow-a` for real-world usage.
318
+
319
+ Proceed to `vercel-deploy-preview` for preview deployment workflows.
@@ -0,0 +1,11 @@
1
+ # Error Handling Reference
2
+
3
+ | Pattern | Use Case | Benefit |
4
+ |---------|----------|---------|
5
+ | Safe wrapper | All API calls | Prevents uncaught exceptions |
6
+ | Retry logic | Transient failures | Improves reliability |
7
+ | Type guards | Response validation | Catches API changes |
8
+ | Logging | All operations | Debugging and monitoring |
9
+
10
+ ---
11
+ *[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
@@ -0,0 +1,45 @@
1
+ ## Examples
2
+
3
+ ### Factory Pattern (Multi-tenant)
4
+
5
+ ```typescript
6
+ const clients = new Map<string, VercelClient>();
7
+
8
+ export function getClientForTenant(tenantId: string): VercelClient {
9
+ if (!clients.has(tenantId)) {
10
+ const apiKey = getTenantApiKey(tenantId);
11
+ clients.set(tenantId, new VercelClient({ apiKey }));
12
+ }
13
+ return clients.get(tenantId)!;
14
+ }
15
+ ```
16
+
17
+ ### Python Context Manager
18
+
19
+ ```python
20
+ from contextlib import asynccontextmanager
21
+ from None import VercelClient
22
+
23
+ @asynccontextmanager
24
+ async def get_vercel_client():
25
+ client = VercelClient()
26
+ try:
27
+ yield client
28
+ finally:
29
+ await client.close()
30
+ ```
31
+
32
+ ### Zod Validation
33
+
34
+ ```typescript
35
+ import { z } from 'zod';
36
+
37
+ const vercelResponseSchema = z.object({
38
+ id: z.string(),
39
+ status: z.enum(['active', 'inactive']),
40
+ createdAt: z.string().datetime(),
41
+ });
42
+ ```
43
+
44
+ ---
45
+ *[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
@@ -0,0 +1,67 @@
1
+ ## Implementation Guide
2
+
3
+ ### Step 1: Implement Singleton Pattern (Recommended)
4
+
5
+ ```typescript
6
+ // src/vercel/client.ts
7
+ import { VercelClient } from 'vercel';
8
+
9
+ let instance: VercelClient | null = null;
10
+
11
+ export function getVercelClient(): VercelClient {
12
+ if (!instance) {
13
+ instance = new VercelClient({
14
+ apiKey: process.env.VERCEL_API_KEY!,
15
+ // Additional options
16
+ });
17
+ }
18
+ return instance;
19
+ }
20
+ ```
21
+
22
+ ### Step 2: Add Error Handling Wrapper
23
+
24
+ ```typescript
25
+ import { VercelError } from 'vercel';
26
+
27
+ async function safeVercelCall<T>(
28
+ operation: () => Promise<T>
29
+ ): Promise<{ data: T | null; error: Error | null }> {
30
+ try {
31
+ const data = await operation();
32
+ return { data, error: null };
33
+ } catch (err) {
34
+ if (err instanceof VercelError) {
35
+ console.error({
36
+ code: err.code,
37
+ message: err.message,
38
+ });
39
+ }
40
+ return { data: null, error: err as Error };
41
+ }
42
+ }
43
+ ```
44
+
45
+ ### Step 3: Implement Retry Logic
46
+
47
+ ```typescript
48
+ async function withRetry<T>(
49
+ operation: () => Promise<T>,
50
+ maxRetries = 3,
51
+ backoffMs = 1000
52
+ ): Promise<T> {
53
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
54
+ try {
55
+ return await operation();
56
+ } catch (err) {
57
+ if (attempt === maxRetries) throw err;
58
+ const delay = backoffMs * Math.pow(2, attempt - 1);
59
+ await new Promise(r => setTimeout(r, delay));
60
+ }
61
+ }
62
+ throw new Error('Unreachable');
63
+ }
64
+ ```
65
+
66
+ ---
67
+ *[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*