@4players/payment 1.0.0 → 1.0.1-beta.2

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 4Players GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,272 @@
1
+ # @4players/payment
2
+
3
+ Official TypeScript SDK for the [4Players Payment API](https://docs.4players.io/). Manage projects, billing accounts, invoices, access keys, and user permissions with full type safety.
4
+
5
+ Works in Node.js, Deno, Bun, browsers, and edge runtimes.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @4players/payment
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { PaymentClient } from '@4players/payment';
17
+
18
+ const client = new PaymentClient({
19
+ sessionId: 'your-fusion-sid',
20
+ });
21
+
22
+ // List all projects
23
+ const projects = await client.getPaymentProjects();
24
+ console.log(projects);
25
+
26
+ // Get a specific project
27
+ const project = await client.getProject('project-id');
28
+ console.log(project.name, project.subscription);
29
+ ```
30
+
31
+ ## Authentication
32
+
33
+ The API uses session-based authentication via the `fusion-sid` HTTP header. Pass your session ID when creating the client:
34
+
35
+ ```typescript
36
+ const client = new PaymentClient({
37
+ sessionId: 'your-fusion-sid',
38
+ });
39
+ ```
40
+
41
+ ## Configuration
42
+
43
+ ```typescript
44
+ const client = new PaymentClient({
45
+ // Required: your fusion session ID
46
+ sessionId: 'your-fusion-sid',
47
+
48
+ // Optional: override the base URL (default: https://secure.4players.de/public/api/v1)
49
+ baseUrl: 'https://your-custom-url/api/v1',
50
+
51
+ // Optional: provide a custom fetch implementation
52
+ fetch: customFetchFn,
53
+ });
54
+ ```
55
+
56
+ ## API Reference
57
+
58
+ ### Projects
59
+
60
+ ```typescript
61
+ // List all projects
62
+ const projects = await client.getPaymentProjects();
63
+
64
+ // Get project for a specific app
65
+ const project = await client.getPaymentProjectForApp('app-id');
66
+
67
+ // Get project details
68
+ const project = await client.getProject('project-id');
69
+
70
+ // Update a project
71
+ await client.editProject('project-id', {
72
+ name: 'New Name',
73
+ description: 'Updated description',
74
+ });
75
+ ```
76
+
77
+ ### Billing
78
+
79
+ ```typescript
80
+ // List billing accounts
81
+ const accounts = await client.getBillingAccounts();
82
+
83
+ // Get a specific billing account
84
+ const account = await client.getBillingAccount('billing-account-id');
85
+
86
+ // Get billing options for a project
87
+ const options = await client.getBillingOptions('project-id');
88
+
89
+ // Assign a billing account to a project
90
+ await client.setBillingAccount('project-id', {
91
+ billingAccountId: 'billing-account-id',
92
+ billingState: 'active',
93
+ });
94
+
95
+ // Cancel billing for a project
96
+ await client.cancelBilling('project-id');
97
+
98
+ // Create a Stripe setup session for a new billing account
99
+ const session = await client.createSetupSession({
100
+ name: 'My Company',
101
+ email: 'billing@example.com',
102
+ successUrl: 'https://example.com/success',
103
+ cancelUrl: 'https://example.com/cancel',
104
+ });
105
+
106
+ // Create a Stripe billing portal session
107
+ const portal = await client.createBillingPortalSession('billing-account-id', {
108
+ returnUrl: 'https://example.com/billing',
109
+ });
110
+ ```
111
+
112
+ ### Invoices
113
+
114
+ ```typescript
115
+ // List all invoices
116
+ const invoices = await client.getInvoices();
117
+
118
+ // List invoices for a billing account
119
+ const invoices = await client.getBillingAccountInvoices('billing-account-id');
120
+
121
+ // Preview the current month's invoice for a project
122
+ const preview = await client.getInvoicePreview('project-id');
123
+ ```
124
+
125
+ ### Access Keys
126
+
127
+ ```typescript
128
+ // Get an access key
129
+ const key = await client.getAccessKey('key-id');
130
+
131
+ // Create a new access key
132
+ const newKey = await client.createAccessKey({
133
+ projectId: 'project-id',
134
+ name: 'My Access Key',
135
+ });
136
+
137
+ // Update an access key
138
+ await client.editAccessKey('key-id', { name: 'Renamed Key' });
139
+
140
+ // Delete an access key
141
+ await client.deleteAccessKey('key-id');
142
+ ```
143
+
144
+ ### Project Members
145
+
146
+ ```typescript
147
+ // Add a user to a project
148
+ const userRole = await client.addProjectMember('project-id', {
149
+ email: 'user@example.com',
150
+ role: 'developer',
151
+ });
152
+
153
+ // Change a member's role
154
+ await client.changeMemberRole('project-id', {
155
+ permissionId: 'permission-id',
156
+ role: 'admin',
157
+ });
158
+
159
+ // Remove a user from a project
160
+ await client.deleteProjectMember('project-id', {
161
+ permissionId: 'permission-id',
162
+ });
163
+ ```
164
+
165
+ ### Tokens & Secrets
166
+
167
+ ```typescript
168
+ // Create an ODIN access token
169
+ const token = await client.createAccessToken('project-id', {
170
+ roomId: 'my-room',
171
+ userId: 'user-123',
172
+ });
173
+
174
+ // Revoke and regenerate a project's secret
175
+ const updatedProject = await client.revokeSecret('project-id');
176
+ ```
177
+
178
+ ### Metrics
179
+
180
+ ```typescript
181
+ // Get peak peers over time
182
+ const peers = await client.getPeersOverTime('project-id', {
183
+ start: 1700000000, // Unix timestamp
184
+ });
185
+ ```
186
+
187
+ ### Resource Pricing
188
+
189
+ ```typescript
190
+ // Get price for a single resource package
191
+ const price = await client.getResourcePackagePrice('project-id', {
192
+ resourcePackageId: 'package-id',
193
+ region: 'eu',
194
+ amount: 1,
195
+ });
196
+
197
+ // Get prices for multiple resource packages
198
+ const prices = await client.getResourcePackagePrices('project-id', {
199
+ resourcePackageIds: ['package-1', 'package-2'],
200
+ region: 'eu',
201
+ amount: 1,
202
+ });
203
+ ```
204
+
205
+ ## Error Handling
206
+
207
+ The SDK provides structured error classes:
208
+
209
+ ```typescript
210
+ import {
211
+ PaymentClient,
212
+ PaymentApiError,
213
+ PaymentAuthError,
214
+ PaymentNotFoundError,
215
+ PaymentRateLimitError,
216
+ } from '@4players/payment';
217
+
218
+ try {
219
+ const project = await client.getProject('invalid-id');
220
+ } catch (err) {
221
+ if (err instanceof PaymentApiError) {
222
+ // Application-level error from the API response envelope
223
+ console.error(`API error ${err.code}: ${err.message} (HTTP ${err.httpStatus})`);
224
+ } else if (err instanceof PaymentAuthError) {
225
+ // 401/403 - invalid or expired session
226
+ console.error('Authentication failed');
227
+ } else if (err instanceof PaymentNotFoundError) {
228
+ // 404 - resource not found
229
+ console.error(err.message);
230
+ } else if (err instanceof PaymentRateLimitError) {
231
+ // 429 - rate limited
232
+ console.error(err.message);
233
+ }
234
+ }
235
+ ```
236
+
237
+ > **Note:** The Payment API can return application-level errors even with HTTP 200 status codes (legacy behavior). The SDK detects these automatically and throws `PaymentApiError`.
238
+
239
+ ## Examples
240
+
241
+ See the [examples/](examples/) directory for runnable scripts:
242
+
243
+ ```bash
244
+ npx tsx examples/list-projects.ts
245
+ npx tsx examples/project-details.ts [projectId]
246
+ npx tsx examples/billing-and-invoices.ts
247
+ ```
248
+
249
+ Each script prompts for your `fusion-sid` and queries the live API.
250
+
251
+ ## Development
252
+
253
+ ```bash
254
+ # Install dependencies
255
+ npm install
256
+
257
+ # Generate types from OpenAPI spec
258
+ npm run generate:types
259
+
260
+ # Build the SDK
261
+ npm run build
262
+
263
+ # Type-check without emitting
264
+ npm run typecheck
265
+
266
+ # Build in watch mode
267
+ npm run dev
268
+ ```
269
+
270
+ ## License
271
+
272
+ [MIT](LICENSE)
package/dist/index.cjs CHANGED
@@ -169,28 +169,42 @@ var PaymentClient = class {
169
169
  error
170
170
  );
171
171
  }
172
- // ==================== Projects ====================
172
+ // ==================== Fleet Apps ====================
173
173
  /**
174
- * Get all projects the user has access to.
174
+ * Get all fleet apps the user has access to (projects with Fleet activated).
175
175
  *
176
- * @returns Array of payment projects
176
+ * @returns Array of payment projects with Fleet app IDs
177
177
  */
178
- async getPaymentProjects() {
178
+ async getFleetProjects() {
179
179
  const { data, error } = await this.client.GET("/apps");
180
- if (error) this.handleError("get payment projects", error);
180
+ if (error) this.handleError("get fleet projects", error);
181
181
  return data;
182
182
  }
183
183
  /**
184
- * Get the details of a specific app including the payment project.
184
+ * Get the details of a specific fleet app including the payment project.
185
185
  *
186
- * @param appId - The ID of the app to retrieve
186
+ * @param appId - The ID of the fleet app to retrieve
187
187
  * @returns Payment project details
188
188
  */
189
- async getPaymentProjectForApp(appId) {
189
+ async getFleetProject(appId) {
190
190
  const { data, error } = await this.client.GET("/apps/{app_id}", {
191
191
  params: { path: { app_id: appId } }
192
192
  });
193
- if (error) this.handleError("get payment project for app", error);
193
+ if (error) this.handleError("get fleet project", error);
194
+ return data;
195
+ }
196
+ // ==================== Projects ====================
197
+ /**
198
+ * Get all projects the authenticated user has access to.
199
+ *
200
+ * @param query - Optional query parameters to filter by project type
201
+ * @returns Array of payment projects
202
+ */
203
+ async getProjects(query) {
204
+ const { data, error } = await this.client.GET("/projects", {
205
+ params: { query }
206
+ });
207
+ if (error) this.handleError("get projects", error);
194
208
  return data;
195
209
  }
196
210
  /**
@@ -342,6 +356,22 @@ var PaymentClient = class {
342
356
  if (error) this.handleError("cancel billing", error);
343
357
  return data;
344
358
  }
359
+ // ==================== API Activation ====================
360
+ /**
361
+ * Activate an API for the specified project.
362
+ *
363
+ * @param projectId - The unique identifier of the project
364
+ * @param body - The API slug to activate
365
+ * @returns Success response
366
+ */
367
+ async activateAPI(projectId, body) {
368
+ const { data, error } = await this.client.POST("/projects/{projectId}/activate-api", {
369
+ params: { path: { projectId } },
370
+ body
371
+ });
372
+ if (error) this.handleError("activate API", error);
373
+ return data;
374
+ }
345
375
  // ==================== Invoices ====================
346
376
  /**
347
377
  * Get all invoices for the current user, optionally filtered by ID.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":["createClient"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Payment SDK Error Classes\n *\n * Provides structured error handling for Payment API operations.\n */\n\n// V8-specific stack trace capture (available in Node.js, Chrome, etc.)\ndeclare const Error: ErrorConstructor & {\n captureStackTrace?(targetObject: object, constructorOpt?: Function): void;\n};\n\n/**\n * Base error class for all Payment SDK errors.\n */\nexport class PaymentError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n public readonly details?: unknown\n ) {\n super(message);\n this.name = \"PaymentError\";\n // Maintains proper stack trace for where error was thrown (V8 engines)\n if (typeof Error.captureStackTrace === \"function\") {\n Error.captureStackTrace(this, PaymentError);\n }\n }\n}\n\n/**\n * Error thrown when the Payment API returns an application-level error\n * in its response envelope.\n *\n * The Payment API wraps all responses in an envelope:\n * ```json\n * { \"data\": T | null, \"error\": { \"code\": number, \"message\": string } }\n * ```\n *\n * A `PaymentApiError` is thrown when:\n * - `error.code !== 0` (application-level error, even if HTTP status is 200)\n * - `data` is `null` (legacy error pattern from before HTTP status codes were used)\n */\nexport class PaymentApiError extends PaymentError {\n /**\n * Application-level error code from the response envelope.\n * A value of `0` means no specific error code was returned (legacy null-data case).\n */\n public readonly code: number;\n\n /**\n * The HTTP status code of the response.\n * Note: This may be `200` even when there is an application error.\n */\n public readonly httpStatus: number;\n\n constructor(message: string, code: number, httpStatus: number) {\n super(message, httpStatus);\n this.name = \"PaymentApiError\";\n this.code = code;\n this.httpStatus = httpStatus;\n }\n}\n\n/**\n * Error thrown when authentication fails or is required.\n */\nexport class PaymentAuthError extends PaymentError {\n constructor(message = \"Authentication required. Please provide a valid session ID.\") {\n super(message, 401);\n this.name = \"PaymentAuthError\";\n }\n}\n\n/**\n * Error thrown when a requested resource is not found.\n */\nexport class PaymentNotFoundError extends PaymentError {\n constructor(resource: string, id: string) {\n super(`${resource} with ID ${id} not found`, 404);\n this.name = \"PaymentNotFoundError\";\n }\n}\n\n/**\n * Error thrown when request validation fails.\n */\nexport class PaymentValidationError extends PaymentError {\n constructor(message: string, details?: unknown) {\n super(message, 422, details);\n this.name = \"PaymentValidationError\";\n }\n}\n\n/**\n * Error thrown when the API rate limit is exceeded.\n */\nexport class PaymentRateLimitError extends PaymentError {\n constructor(retryAfter?: number) {\n super(\n retryAfter\n ? `Rate limit exceeded. Retry after ${retryAfter} seconds.`\n : \"Rate limit exceeded. Please try again later.\",\n 429,\n { retryAfter }\n );\n this.name = \"PaymentRateLimitError\";\n }\n}\n","/**\n * 4Players Payment API Client\n *\n * A type-safe client for the 4Players Payment API.\n * Works in browsers, Node.js, Deno, Bun, and edge runtimes.\n *\n * @example\n * ```typescript\n * import { PaymentClient } from '@4players/payment';\n *\n * const client = new PaymentClient({ sessionId: 'your-session-id' });\n *\n * const projects = await client.getPaymentProjects();\n * ```\n */\n\nimport createClient, { type Middleware } from \"openapi-fetch\";\nimport type { paths, components, operations } from \"./types.js\";\nimport {\n PaymentError,\n PaymentApiError,\n PaymentAuthError,\n PaymentNotFoundError,\n PaymentRateLimitError,\n} from \"./errors.js\";\n\nconst DEFAULT_BASE_URL = \"https://secure.4players.de/public/api/v1\";\n\n/**\n * Configuration options for the Payment client.\n */\nexport interface PaymentClientConfig {\n /** Fusion session ID for authentication (sent as fusion-sid header) */\n sessionId: string;\n /** Base URL for the Payment API (default: https://secure.4players.de/public/api/v1) */\n baseUrl?: string;\n /** Custom fetch implementation (useful for testing or special environments) */\n fetch?: typeof fetch;\n}\n\n// ==================== Entity types from components.schemas ====================\n\nexport type PaymentProject = components[\"schemas\"][\"PaymentProject\"];\nexport type BillingAccount = components[\"schemas\"][\"BillingAccount\"];\nexport type OdinAccessKey = components[\"schemas\"][\"OdinAccessKey\"];\nexport type OdinUserPermissions = components[\"schemas\"][\"OdinUserPermissions\"];\nexport type OdinUserRole = components[\"schemas\"][\"OdinUserRole\"];\nexport type OdinPeersOverTime = components[\"schemas\"][\"OdinPeersOverTime\"];\nexport type Subscription = components[\"schemas\"][\"Subscription\"];\nexport type Invoice = components[\"schemas\"][\"Invoice\"];\nexport type InvoicePosition = components[\"schemas\"][\"InvoicePosition\"];\nexport type Invoices = components[\"schemas\"][\"Invoices\"];\nexport type SubscriptionPosition = components[\"schemas\"][\"SubscriptionPosition\"];\nexport type TariffParams = components[\"schemas\"][\"TariffParams\"];\nexport type SetupSession = components[\"schemas\"][\"SetupSession\"];\nexport type PortalSession = components[\"schemas\"][\"PortalSession\"];\nexport type TokenPayload = components[\"schemas\"][\"TokenPayload\"];\nexport type BillingOptions = components[\"schemas\"][\"BillingOptions\"];\nexport type BillingChangeOptions = components[\"schemas\"][\"BillingChangeOptions\"];\nexport type BillingStateHistory = components[\"schemas\"][\"BillingStateHistory\"];\nexport type ResourcePackagePrice = components[\"schemas\"][\"ResourcePackagePrice\"];\nexport type SuccessResponse = components[\"schemas\"][\"SuccessResponse\"];\n\n// Enum types\nexport type BillingState = components[\"schemas\"][\"BillingState\"];\nexport type PermissionRole = components[\"schemas\"][\"PermissionRole\"];\nexport type UserStatus = components[\"schemas\"][\"UserStatus\"];\nexport type InvoiceStatus = components[\"schemas\"][\"InvoiceStatus\"];\n\n// ==================== Request/Payload types ====================\n\nexport type AddUserToProjectPayload = components[\"schemas\"][\"AddUserToProjectPayload\"];\nexport type ChangeUserRolePayload = components[\"schemas\"][\"ChangeUserRolePayload\"];\nexport type CreateAccessKeyPayload = components[\"schemas\"][\"CreateAccessKeyPayload\"];\nexport type CreateBillingPortalSessionPayload = components[\"schemas\"][\"CreateBillingPortalSessionPayload\"];\nexport type CreateSetupSessionPayload = components[\"schemas\"][\"CreateSetupSessionPayload\"];\nexport type CreateTokenPayload = components[\"schemas\"][\"CreateTokenPayload\"];\nexport type EditAccessKeyPayload = components[\"schemas\"][\"EditAccessKeyPayload\"];\nexport type EditProjectPayload = components[\"schemas\"][\"EditProjectPayload\"];\nexport type ResourcePackagePricePayload = components[\"schemas\"][\"ResourcePackagePricePayload\"];\nexport type ResourcePackagePricesPayload = components[\"schemas\"][\"ResourcePackagePricesPayload\"];\nexport type RevokeUserPayload = components[\"schemas\"][\"RevokeUserPayload\"];\nexport type SetBillingAccountPayload = components[\"schemas\"][\"SetBillingAccountPayload\"];\n\n// ==================== Query parameter types ====================\n\nexport type GetPeersOverTimeQuery = operations[\"getPeersOverTime\"][\"parameters\"][\"query\"];\nexport type GetInvoicesQuery = operations[\"getInvoices\"][\"parameters\"][\"query\"];\n\n// ==================== Response types ====================\n\nexport type GetPaymentProjectsResponse = operations[\"getPaymentProjects\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetPaymentProjectForAppResponse = operations[\"getPaymentProjectForApp\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetPeersOverTimeResponse = operations[\"getPeersOverTime\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetBillingAccountsResponse = operations[\"getBillingAccounts\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetBillingAccountResponse = operations[\"getBillingAccount\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetBillingAccountInvoicesResponse = operations[\"getBillingAccountInvoices\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetProjectResponse = operations[\"getProject\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetAccessKeyResponse = operations[\"getAccessKey\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetInvoicesResponse = operations[\"getInvoices\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetBillingOptionsResponse = operations[\"getBillingOptions\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetInvoicePreviewResponse = operations[\"getInvoicePreview\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type CreateAccessKeyResponse = operations[\"createAccessKey\"][\"responses\"][\"201\"][\"content\"][\"application/json\"];\nexport type CreateSetupSessionResponse = operations[\"createSetupSession\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type CreateBillingPortalSessionResponse = operations[\"createBillingPortalSession\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type CreateAccessTokenResponse = operations[\"createAccessToken\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\n\n/**\n * Response envelope used by the Payment API.\n */\ninterface PaymentEnvelope<T = unknown> {\n data: T | null;\n error: {\n code: number;\n message: string;\n };\n}\n\n/**\n * 4Players Payment API Client\n *\n * Provides a type-safe interface to the 4Players Payment REST API for managing\n * projects, billing, invoices, access keys, and user permissions.\n */\nexport class PaymentClient {\n private client: ReturnType<typeof createClient<paths>>;\n\n /**\n * Create a new Payment client instance.\n *\n * @param config - Client configuration\n * @throws {PaymentAuthError} If no session ID is provided\n *\n * @example\n * ```typescript\n * const client = new PaymentClient({\n * sessionId: 'your-fusion-sid'\n * });\n * ```\n */\n constructor(config: PaymentClientConfig) {\n if (!config.sessionId) {\n throw new PaymentAuthError(\"Session ID is required\");\n }\n\n this.client = createClient<paths>({\n baseUrl: config.baseUrl || DEFAULT_BASE_URL,\n headers: {\n \"fusion-sid\": config.sessionId,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n fetch: config.fetch,\n });\n\n // Register the envelope-unwrapping middleware\n this.client.use(this.createEnvelopeMiddleware());\n }\n\n /**\n * Creates middleware that unwraps the Payment API response envelope.\n *\n * The Payment API wraps ALL responses in `{ data, error }`.\n * This middleware:\n * 1. Checks `error.code` — if non-zero, throws `PaymentApiError`\n * 2. Checks `data` — if null, throws `PaymentApiError` (legacy error pattern)\n * 3. Returns a new Response containing only the unwrapped `data`\n */\n private createEnvelopeMiddleware(): Middleware {\n return {\n async onResponse({ response }) {\n const contentType = response.headers.get(\"content-type\");\n if (!contentType?.includes(\"application/json\")) {\n return response;\n }\n\n const text = await response.clone().text();\n let body: unknown;\n try {\n body = JSON.parse(text);\n } catch {\n return response;\n }\n\n if (\n body !== null &&\n typeof body === \"object\" &&\n \"error\" in body &&\n \"data\" in body\n ) {\n const envelope = body as PaymentEnvelope;\n\n // Application-level error (can happen even with HTTP 200!)\n if (envelope.error && envelope.error.code !== 0) {\n throw new PaymentApiError(\n envelope.error.message,\n envelope.error.code,\n response.status\n );\n }\n\n // Legacy error pattern: data is null with HTTP 200\n if (envelope.data === null || envelope.data === undefined) {\n throw new PaymentApiError(\n envelope.error?.message || \"Response data is null\",\n envelope.error?.code || 0,\n response.status\n );\n }\n\n // Return unwrapped data so openapi-fetch sees the schema-matching body\n return new Response(JSON.stringify(envelope.data), {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n\n // Not an envelope — return as-is\n return response;\n },\n };\n }\n\n private handleError(operation: string, error: unknown): never {\n if (error && typeof error === \"object\") {\n const errorObj = error as Record<string, unknown>;\n\n if (errorObj.status === 401 || errorObj.status === 403) {\n throw new PaymentAuthError();\n }\n if (errorObj.status === 404) {\n throw new PaymentNotFoundError(operation, \"unknown\");\n }\n if (errorObj.status === 429) {\n throw new PaymentRateLimitError();\n }\n }\n\n throw new PaymentError(\n `Failed to ${operation}: ${JSON.stringify(error)}`,\n undefined,\n error\n );\n }\n\n // ==================== Projects ====================\n\n /**\n * Get all projects the user has access to.\n *\n * @returns Array of payment projects\n */\n async getPaymentProjects(): Promise<GetPaymentProjectsResponse> {\n const { data, error } = await this.client.GET(\"/apps\");\n if (error) this.handleError(\"get payment projects\", error);\n return data!;\n }\n\n /**\n * Get the details of a specific app including the payment project.\n *\n * @param appId - The ID of the app to retrieve\n * @returns Payment project details\n */\n async getPaymentProjectForApp(appId: string): Promise<GetPaymentProjectForAppResponse> {\n const { data, error } = await this.client.GET(\"/apps/{app_id}\", {\n params: { path: { app_id: appId } },\n });\n if (error) this.handleError(\"get payment project for app\", error);\n return data!;\n }\n\n /**\n * Get a specific project by ID.\n *\n * @param projectId - The unique identifier of the project\n * @returns Project details\n */\n async getProject(projectId: string): Promise<GetProjectResponse> {\n const { data, error } = await this.client.GET(\"/projects/{projectId}\", {\n params: { path: { projectId } },\n });\n if (error) this.handleError(\"get project\", error);\n return data!;\n }\n\n /**\n * Update a project's name, description, or peer limit.\n *\n * @param projectId - The unique identifier of the project\n * @param body - Updated project fields\n * @returns Success response\n */\n async editProject(projectId: string, body: EditProjectPayload): Promise<SuccessResponse> {\n const { data, error } = await this.client.PUT(\"/projects/{projectId}\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"edit project\", error);\n return data!;\n }\n\n // ==================== Peers / Metrics ====================\n\n /**\n * Get peak peers over time for a project.\n *\n * @param projectId - The unique identifier of the project\n * @param query - Query parameters (start timestamp is required)\n * @returns Peers over time data\n */\n async getPeersOverTime(projectId: string, query: GetPeersOverTimeQuery): Promise<GetPeersOverTimeResponse> {\n const { data, error } = await this.client.GET(\"/projects/{projectId}/peers-over-time\", {\n params: { path: { projectId }, query },\n });\n if (error) this.handleError(\"get peers over time\", error);\n return data!;\n }\n\n // ==================== Billing ====================\n\n /**\n * Get all billing accounts for the current user.\n *\n * @returns Array of billing accounts\n */\n async getBillingAccounts(): Promise<GetBillingAccountsResponse> {\n const { data, error } = await this.client.GET(\"/billing\");\n if (error) this.handleError(\"get billing accounts\", error);\n return data!;\n }\n\n /**\n * Get a specific billing account.\n *\n * @param billingAccountId - The unique identifier of the billing account\n * @returns Billing account details\n */\n async getBillingAccount(billingAccountId: string): Promise<GetBillingAccountResponse> {\n const { data, error } = await this.client.GET(\"/billing/{billingAccountId}\", {\n params: { path: { billingAccountId } },\n });\n if (error) this.handleError(\"get billing account\", error);\n return data!;\n }\n\n /**\n * Get invoices for a specific billing account.\n *\n * @param billingAccountId - The unique identifier of the billing account\n * @returns Array of invoices\n */\n async getBillingAccountInvoices(billingAccountId: string): Promise<GetBillingAccountInvoicesResponse> {\n const { data, error } = await this.client.GET(\"/billing/{billingAccountId}/invoices\", {\n params: { path: { billingAccountId } },\n });\n if (error) this.handleError(\"get billing account invoices\", error);\n return data!;\n }\n\n /**\n * Create a Stripe setup session for a new billing account.\n *\n * @param body - Setup session creation payload\n * @returns Setup session with redirect URL\n */\n async createSetupSession(body: CreateSetupSessionPayload): Promise<CreateSetupSessionResponse> {\n const { data, error } = await this.client.POST(\"/billing/create-setup-session\", {\n body,\n });\n if (error) this.handleError(\"create setup session\", error);\n return data!;\n }\n\n /**\n * Create a Stripe billing portal session.\n *\n * @param billingAccountId - The unique identifier of the billing account\n * @param body - Portal session creation payload\n * @returns Portal session with redirect URL\n */\n async createBillingPortalSession(billingAccountId: string, body: CreateBillingPortalSessionPayload): Promise<CreateBillingPortalSessionResponse> {\n const { data, error } = await this.client.POST(\"/billing/{billingAccountId}/create-billing-portal-session\", {\n params: { path: { billingAccountId } },\n body,\n });\n if (error) this.handleError(\"create billing portal session\", error);\n return data!;\n }\n\n /**\n * Get billing options for a project.\n *\n * @param projectId - The unique identifier of the project\n * @returns Billing options including current state and change options\n */\n async getBillingOptions(projectId: string): Promise<GetBillingOptionsResponse> {\n const { data, error } = await this.client.GET(\"/projects/{projectId}/get-billing-options\", {\n params: { path: { projectId } },\n });\n if (error) this.handleError(\"get billing options\", error);\n return data!;\n }\n\n /**\n * Set a billing account on a project.\n *\n * @param projectId - The unique identifier of the project\n * @param body - Billing account and state to set\n * @returns Success response\n */\n async setBillingAccount(projectId: string, body: SetBillingAccountPayload): Promise<SuccessResponse> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/set-billing-account\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"set billing account\", error);\n return data!;\n }\n\n /**\n * Cancel billing for a project.\n *\n * @param projectId - The unique identifier of the project\n * @returns Success response\n */\n async cancelBilling(projectId: string): Promise<SuccessResponse> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/cancel-billing\", {\n params: { path: { projectId } },\n });\n if (error) this.handleError(\"cancel billing\", error);\n return data!;\n }\n\n // ==================== Invoices ====================\n\n /**\n * Get all invoices for the current user, optionally filtered by ID.\n *\n * @param query - Optional query parameters for filtering by invoice IDs\n * @returns Array of invoices\n */\n async getInvoices(query?: GetInvoicesQuery): Promise<GetInvoicesResponse> {\n const { data, error } = await this.client.GET(\"/invoices\", {\n params: { query },\n });\n if (error) this.handleError(\"get invoices\", error);\n return data!;\n }\n\n /**\n * Get a preview of the current month's invoice for a project.\n *\n * @param projectId - The unique identifier of the project\n * @returns Invoice preview\n */\n async getInvoicePreview(projectId: string): Promise<GetInvoicePreviewResponse> {\n const { data, error } = await this.client.GET(\"/projects/{projectId}/preview-invoice\", {\n params: { path: { projectId } },\n });\n if (error) this.handleError(\"get invoice preview\", error);\n return data!;\n }\n\n // ==================== Access Keys ====================\n\n /**\n * Get a specific access key.\n *\n * @param accessKeyId - The unique identifier of the access key\n * @returns Access key details\n */\n async getAccessKey(accessKeyId: string): Promise<GetAccessKeyResponse> {\n const { data, error } = await this.client.GET(\"/odin-access-keys/{accessKeyId}\", {\n params: { path: { accessKeyId } },\n });\n if (error) this.handleError(\"get access key\", error);\n return data!;\n }\n\n /**\n * Create a new access key for a project.\n *\n * @param body - Access key creation payload\n * @returns Created access key (includes the key value only in this response)\n */\n async createAccessKey(body: CreateAccessKeyPayload): Promise<CreateAccessKeyResponse> {\n const { data, error } = await this.client.POST(\"/odin-access-keys/\", {\n body,\n });\n if (error) this.handleError(\"create access key\", error);\n return data!;\n }\n\n /**\n * Update an existing access key's name or description.\n *\n * @param accessKeyId - The unique identifier of the access key\n * @param body - Updated access key fields\n * @returns Success response\n */\n async editAccessKey(accessKeyId: string, body: EditAccessKeyPayload): Promise<SuccessResponse> {\n const { data, error } = await this.client.PUT(\"/odin-access-keys/{accessKeyId}\", {\n params: { path: { accessKeyId } },\n body,\n });\n if (error) this.handleError(\"edit access key\", error);\n return data!;\n }\n\n /**\n * Delete an access key. This operation is irreversible.\n *\n * @param accessKeyId - The unique identifier of the access key\n * @returns Success response\n */\n async deleteAccessKey(accessKeyId: string): Promise<SuccessResponse> {\n const { data, error } = await this.client.DELETE(\"/odin-access-keys/{accessKeyId}\", {\n params: { path: { accessKeyId } },\n });\n if (error) this.handleError(\"delete access key\", error);\n return data!;\n }\n\n // ==================== Project Members ====================\n\n /**\n * Add a user to a project with a specified role.\n *\n * @param projectId - The unique identifier of the project\n * @param body - User email and role\n * @returns The created user role\n */\n async addProjectMember(projectId: string, body: AddUserToProjectPayload): Promise<OdinUserRole> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/add-user-permission\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"add project member\", error);\n return data!;\n }\n\n /**\n * Revoke a user's permission from a project.\n *\n * @param projectId - The unique identifier of the project\n * @param body - The permission ID to revoke\n * @returns Success response\n */\n async deleteProjectMember(projectId: string, body: RevokeUserPayload): Promise<SuccessResponse> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/revoke-user-permission\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"delete project member\", error);\n return data!;\n }\n\n /**\n * Change a project member's role.\n *\n * @param projectId - The unique identifier of the project\n * @param body - The permission ID and new role\n * @returns Success response\n */\n async changeMemberRole(projectId: string, body: ChangeUserRolePayload): Promise<SuccessResponse> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/change-user-role\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"change member role\", error);\n return data!;\n }\n\n // ==================== Tokens & Secrets ====================\n\n /**\n * Create an ODIN access token for a project.\n *\n * @param projectId - The unique identifier of the project\n * @param body - Token creation payload\n * @returns The created token\n */\n async createAccessToken(projectId: string, body: CreateTokenPayload): Promise<CreateAccessTokenResponse> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/create-token\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"create access token\", error);\n return data!;\n }\n\n /**\n * Revoke the secret for a project.\n *\n * @param projectId - The unique identifier of the project\n * @returns Updated project with new secret\n */\n async revokeSecret(projectId: string): Promise<PaymentProject> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/revoke-secret\", {\n params: { path: { projectId } },\n });\n if (error) this.handleError(\"revoke secret\", error);\n return data!;\n }\n\n // ==================== Resource Package Pricing ====================\n\n /**\n * Get the price for a single resource package in a specific region.\n *\n * @param projectId - The unique identifier of the project\n * @param body - Resource package, region, and quantity\n * @returns Price information\n */\n async getResourcePackagePrice(projectId: string, body: ResourcePackagePricePayload): Promise<ResourcePackagePrice> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/resource-package-price\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"get resource package price\", error);\n return data!;\n }\n\n /**\n * Get prices for multiple resource packages in a specific region.\n *\n * @param projectId - The unique identifier of the project\n * @param body - Resource package IDs, region, and quantity\n * @returns Array of price information\n */\n async getResourcePackagePrices(projectId: string, body: ResourcePackagePricesPayload): Promise<ResourcePackagePrice[]> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/resource-package-prices\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"get resource package prices\", error);\n return data!;\n }\n}\n\nexport default PaymentClient;\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":["createClient"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Payment SDK Error Classes\n *\n * Provides structured error handling for Payment API operations.\n */\n\n// V8-specific stack trace capture (available in Node.js, Chrome, etc.)\ndeclare const Error: ErrorConstructor & {\n captureStackTrace?(targetObject: object, constructorOpt?: Function): void;\n};\n\n/**\n * Base error class for all Payment SDK errors.\n */\nexport class PaymentError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n public readonly details?: unknown\n ) {\n super(message);\n this.name = \"PaymentError\";\n // Maintains proper stack trace for where error was thrown (V8 engines)\n if (typeof Error.captureStackTrace === \"function\") {\n Error.captureStackTrace(this, PaymentError);\n }\n }\n}\n\n/**\n * Error thrown when the Payment API returns an application-level error\n * in its response envelope.\n *\n * The Payment API wraps all responses in an envelope:\n * ```json\n * { \"data\": T | null, \"error\": { \"code\": number, \"message\": string } }\n * ```\n *\n * A `PaymentApiError` is thrown when:\n * - `error.code !== 0` (application-level error, even if HTTP status is 200)\n * - `data` is `null` (legacy error pattern from before HTTP status codes were used)\n */\nexport class PaymentApiError extends PaymentError {\n /**\n * Application-level error code from the response envelope.\n * A value of `0` means no specific error code was returned (legacy null-data case).\n */\n public readonly code: number;\n\n /**\n * The HTTP status code of the response.\n * Note: This may be `200` even when there is an application error.\n */\n public readonly httpStatus: number;\n\n constructor(message: string, code: number, httpStatus: number) {\n super(message, httpStatus);\n this.name = \"PaymentApiError\";\n this.code = code;\n this.httpStatus = httpStatus;\n }\n}\n\n/**\n * Error thrown when authentication fails or is required.\n */\nexport class PaymentAuthError extends PaymentError {\n constructor(message = \"Authentication required. Please provide a valid session ID.\") {\n super(message, 401);\n this.name = \"PaymentAuthError\";\n }\n}\n\n/**\n * Error thrown when a requested resource is not found.\n */\nexport class PaymentNotFoundError extends PaymentError {\n constructor(resource: string, id: string) {\n super(`${resource} with ID ${id} not found`, 404);\n this.name = \"PaymentNotFoundError\";\n }\n}\n\n/**\n * Error thrown when request validation fails.\n */\nexport class PaymentValidationError extends PaymentError {\n constructor(message: string, details?: unknown) {\n super(message, 422, details);\n this.name = \"PaymentValidationError\";\n }\n}\n\n/**\n * Error thrown when the API rate limit is exceeded.\n */\nexport class PaymentRateLimitError extends PaymentError {\n constructor(retryAfter?: number) {\n super(\n retryAfter\n ? `Rate limit exceeded. Retry after ${retryAfter} seconds.`\n : \"Rate limit exceeded. Please try again later.\",\n 429,\n { retryAfter }\n );\n this.name = \"PaymentRateLimitError\";\n }\n}\n","/**\n * 4Players Payment API Client\n *\n * A type-safe client for the 4Players Payment API.\n * Works in browsers, Node.js, Deno, Bun, and edge runtimes.\n *\n * @example\n * ```typescript\n * import { PaymentClient } from '@4players/payment';\n *\n * const client = new PaymentClient({ sessionId: 'your-session-id' });\n *\n * const projects = await client.getProjects();\n * ```\n */\n\nimport createClient, { type Middleware } from \"openapi-fetch\";\nimport type { paths, components, operations } from \"./types.js\";\nimport {\n PaymentError,\n PaymentApiError,\n PaymentAuthError,\n PaymentNotFoundError,\n PaymentRateLimitError,\n} from \"./errors.js\";\n\nconst DEFAULT_BASE_URL = \"https://secure.4players.de/public/api/v1\";\n\n/**\n * Configuration options for the Payment client.\n */\nexport interface PaymentClientConfig {\n /** Fusion session ID for authentication (sent as fusion-sid header) */\n sessionId: string;\n /** Base URL for the Payment API (default: https://secure.4players.de/public/api/v1) */\n baseUrl?: string;\n /** Custom fetch implementation (useful for testing or special environments) */\n fetch?: typeof fetch;\n}\n\n// ==================== Entity types from components.schemas ====================\n\nexport type PaymentProject = components[\"schemas\"][\"PaymentProject\"];\nexport type BillingAccount = components[\"schemas\"][\"BillingAccount\"];\nexport type OdinAccessKey = components[\"schemas\"][\"OdinAccessKey\"];\nexport type OdinUserPermissions = components[\"schemas\"][\"OdinUserPermissions\"];\nexport type OdinUserRole = components[\"schemas\"][\"OdinUserRole\"];\nexport type OdinPeersOverTime = components[\"schemas\"][\"OdinPeersOverTime\"];\nexport type Subscription = components[\"schemas\"][\"Subscription\"];\nexport type Invoice = components[\"schemas\"][\"Invoice\"];\nexport type InvoicePosition = components[\"schemas\"][\"InvoicePosition\"];\nexport type Invoices = components[\"schemas\"][\"Invoices\"];\nexport type SubscriptionPosition = components[\"schemas\"][\"SubscriptionPosition\"];\nexport type TariffParams = components[\"schemas\"][\"TariffParams\"];\nexport type SetupSession = components[\"schemas\"][\"SetupSession\"];\nexport type PortalSession = components[\"schemas\"][\"PortalSession\"];\nexport type TokenPayload = components[\"schemas\"][\"TokenPayload\"];\nexport type BillingOptions = components[\"schemas\"][\"BillingOptions\"];\nexport type BillingChangeOptions = components[\"schemas\"][\"BillingChangeOptions\"];\nexport type BillingStateHistory = components[\"schemas\"][\"BillingStateHistory\"];\nexport type ResourcePackagePrice = components[\"schemas\"][\"ResourcePackagePrice\"];\nexport type SuccessResponse = components[\"schemas\"][\"SuccessResponse\"];\n\n// Enum types\nexport type BillingState = components[\"schemas\"][\"BillingState\"];\nexport type PermissionRole = components[\"schemas\"][\"PermissionRole\"];\nexport type UserStatus = components[\"schemas\"][\"UserStatus\"];\nexport type InvoiceStatus = components[\"schemas\"][\"InvoiceStatus\"];\n\n// ==================== Request/Payload types ====================\n\nexport type ActivateAPIPayload = components[\"schemas\"][\"ActivateAPIPayload\"];\nexport type AddUserToProjectPayload = components[\"schemas\"][\"AddUserToProjectPayload\"];\nexport type ChangeUserRolePayload = components[\"schemas\"][\"ChangeUserRolePayload\"];\nexport type CreateAccessKeyPayload = components[\"schemas\"][\"CreateAccessKeyPayload\"];\nexport type CreateBillingPortalSessionPayload = components[\"schemas\"][\"CreateBillingPortalSessionPayload\"];\nexport type CreateSetupSessionPayload = components[\"schemas\"][\"CreateSetupSessionPayload\"];\nexport type CreateTokenPayload = components[\"schemas\"][\"CreateTokenPayload\"];\nexport type EditAccessKeyPayload = components[\"schemas\"][\"EditAccessKeyPayload\"];\nexport type EditProjectPayload = components[\"schemas\"][\"EditProjectPayload\"];\nexport type ResourcePackagePricePayload = components[\"schemas\"][\"ResourcePackagePricePayload\"];\nexport type ResourcePackagePricesPayload = components[\"schemas\"][\"ResourcePackagePricesPayload\"];\nexport type RevokeUserPayload = components[\"schemas\"][\"RevokeUserPayload\"];\nexport type SetBillingAccountPayload = components[\"schemas\"][\"SetBillingAccountPayload\"];\n\n// ==================== Query parameter types ====================\n\nexport type GetProjectsQuery = operations[\"getProjects\"][\"parameters\"][\"query\"];\nexport type GetPeersOverTimeQuery = operations[\"getPeersOverTime\"][\"parameters\"][\"query\"];\nexport type GetInvoicesQuery = operations[\"getInvoices\"][\"parameters\"][\"query\"];\n\n// ==================== Response types ====================\n\nexport type GetFleetProjectsResponse = operations[\"getFleetProjects\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetFleetProjectResponse = operations[\"getFleetProject\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetProjectsResponse = operations[\"getProjects\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetPeersOverTimeResponse = operations[\"getPeersOverTime\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetBillingAccountsResponse = operations[\"getBillingAccounts\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetBillingAccountResponse = operations[\"getBillingAccount\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetBillingAccountInvoicesResponse = operations[\"getBillingAccountInvoices\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetProjectResponse = operations[\"getProject\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetAccessKeyResponse = operations[\"getAccessKey\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetInvoicesResponse = operations[\"getInvoices\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetBillingOptionsResponse = operations[\"getBillingOptions\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type GetInvoicePreviewResponse = operations[\"getInvoicePreview\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type CreateAccessKeyResponse = operations[\"createAccessKey\"][\"responses\"][\"201\"][\"content\"][\"application/json\"];\nexport type CreateSetupSessionResponse = operations[\"createSetupSession\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type CreateBillingPortalSessionResponse = operations[\"createBillingPortalSession\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\nexport type CreateAccessTokenResponse = operations[\"createAccessToken\"][\"responses\"][\"200\"][\"content\"][\"application/json\"];\n\n/**\n * Response envelope used by the Payment API.\n */\ninterface PaymentEnvelope<T = unknown> {\n data: T | null;\n error: {\n code: number;\n message: string;\n };\n}\n\n/**\n * 4Players Payment API Client\n *\n * Provides a type-safe interface to the 4Players Payment REST API for managing\n * projects, billing, invoices, access keys, and user permissions.\n */\nexport class PaymentClient {\n private client: ReturnType<typeof createClient<paths>>;\n\n /**\n * Create a new Payment client instance.\n *\n * @param config - Client configuration\n * @throws {PaymentAuthError} If no session ID is provided\n *\n * @example\n * ```typescript\n * const client = new PaymentClient({\n * sessionId: 'your-fusion-sid'\n * });\n * ```\n */\n constructor(config: PaymentClientConfig) {\n if (!config.sessionId) {\n throw new PaymentAuthError(\"Session ID is required\");\n }\n\n this.client = createClient<paths>({\n baseUrl: config.baseUrl || DEFAULT_BASE_URL,\n headers: {\n \"fusion-sid\": config.sessionId,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n fetch: config.fetch,\n });\n\n // Register the envelope-unwrapping middleware\n this.client.use(this.createEnvelopeMiddleware());\n }\n\n /**\n * Creates middleware that unwraps the Payment API response envelope.\n *\n * The Payment API wraps ALL responses in `{ data, error }`.\n * This middleware:\n * 1. Checks `error.code` — if non-zero, throws `PaymentApiError`\n * 2. Checks `data` — if null, throws `PaymentApiError` (legacy error pattern)\n * 3. Returns a new Response containing only the unwrapped `data`\n */\n private createEnvelopeMiddleware(): Middleware {\n return {\n async onResponse({ response }) {\n const contentType = response.headers.get(\"content-type\");\n if (!contentType?.includes(\"application/json\")) {\n return response;\n }\n\n const text = await response.clone().text();\n let body: unknown;\n try {\n body = JSON.parse(text);\n } catch {\n return response;\n }\n\n if (\n body !== null &&\n typeof body === \"object\" &&\n \"error\" in body &&\n \"data\" in body\n ) {\n const envelope = body as PaymentEnvelope;\n\n // Application-level error (can happen even with HTTP 200!)\n if (envelope.error && envelope.error.code !== 0) {\n throw new PaymentApiError(\n envelope.error.message,\n envelope.error.code,\n response.status\n );\n }\n\n // Legacy error pattern: data is null with HTTP 200\n if (envelope.data === null || envelope.data === undefined) {\n throw new PaymentApiError(\n envelope.error?.message || \"Response data is null\",\n envelope.error?.code || 0,\n response.status\n );\n }\n\n // Return unwrapped data so openapi-fetch sees the schema-matching body\n return new Response(JSON.stringify(envelope.data), {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n\n // Not an envelope — return as-is\n return response;\n },\n };\n }\n\n private handleError(operation: string, error: unknown): never {\n if (error && typeof error === \"object\") {\n const errorObj = error as Record<string, unknown>;\n\n if (errorObj.status === 401 || errorObj.status === 403) {\n throw new PaymentAuthError();\n }\n if (errorObj.status === 404) {\n throw new PaymentNotFoundError(operation, \"unknown\");\n }\n if (errorObj.status === 429) {\n throw new PaymentRateLimitError();\n }\n }\n\n throw new PaymentError(\n `Failed to ${operation}: ${JSON.stringify(error)}`,\n undefined,\n error\n );\n }\n\n // ==================== Fleet Apps ====================\n\n /**\n * Get all fleet apps the user has access to (projects with Fleet activated).\n *\n * @returns Array of payment projects with Fleet app IDs\n */\n async getFleetProjects(): Promise<GetFleetProjectsResponse> {\n const { data, error } = await this.client.GET(\"/apps\");\n if (error) this.handleError(\"get fleet projects\", error);\n return data!;\n }\n\n /**\n * Get the details of a specific fleet app including the payment project.\n *\n * @param appId - The ID of the fleet app to retrieve\n * @returns Payment project details\n */\n async getFleetProject(appId: string): Promise<GetFleetProjectResponse> {\n const { data, error } = await this.client.GET(\"/apps/{app_id}\", {\n params: { path: { app_id: appId } },\n });\n if (error) this.handleError(\"get fleet project\", error);\n return data!;\n }\n\n // ==================== Projects ====================\n\n /**\n * Get all projects the authenticated user has access to.\n *\n * @param query - Optional query parameters to filter by project type\n * @returns Array of payment projects\n */\n async getProjects(query?: GetProjectsQuery): Promise<GetProjectsResponse> {\n const { data, error } = await this.client.GET(\"/projects\", {\n params: { query },\n });\n if (error) this.handleError(\"get projects\", error);\n return data!;\n }\n\n /**\n * Get a specific project by ID.\n *\n * @param projectId - The unique identifier of the project\n * @returns Project details\n */\n async getProject(projectId: string): Promise<GetProjectResponse> {\n const { data, error } = await this.client.GET(\"/projects/{projectId}\", {\n params: { path: { projectId } },\n });\n if (error) this.handleError(\"get project\", error);\n return data!;\n }\n\n /**\n * Update a project's name, description, or peer limit.\n *\n * @param projectId - The unique identifier of the project\n * @param body - Updated project fields\n * @returns Success response\n */\n async editProject(projectId: string, body: EditProjectPayload): Promise<SuccessResponse> {\n const { data, error } = await this.client.PUT(\"/projects/{projectId}\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"edit project\", error);\n return data!;\n }\n\n // ==================== Peers / Metrics ====================\n\n /**\n * Get peak peers over time for a project.\n *\n * @param projectId - The unique identifier of the project\n * @param query - Query parameters (start timestamp is required)\n * @returns Peers over time data\n */\n async getPeersOverTime(projectId: string, query: GetPeersOverTimeQuery): Promise<GetPeersOverTimeResponse> {\n const { data, error } = await this.client.GET(\"/projects/{projectId}/peers-over-time\", {\n params: { path: { projectId }, query },\n });\n if (error) this.handleError(\"get peers over time\", error);\n return data!;\n }\n\n // ==================== Billing ====================\n\n /**\n * Get all billing accounts for the current user.\n *\n * @returns Array of billing accounts\n */\n async getBillingAccounts(): Promise<GetBillingAccountsResponse> {\n const { data, error } = await this.client.GET(\"/billing\");\n if (error) this.handleError(\"get billing accounts\", error);\n return data!;\n }\n\n /**\n * Get a specific billing account.\n *\n * @param billingAccountId - The unique identifier of the billing account\n * @returns Billing account details\n */\n async getBillingAccount(billingAccountId: string): Promise<GetBillingAccountResponse> {\n const { data, error } = await this.client.GET(\"/billing/{billingAccountId}\", {\n params: { path: { billingAccountId } },\n });\n if (error) this.handleError(\"get billing account\", error);\n return data!;\n }\n\n /**\n * Get invoices for a specific billing account.\n *\n * @param billingAccountId - The unique identifier of the billing account\n * @returns Array of invoices\n */\n async getBillingAccountInvoices(billingAccountId: string): Promise<GetBillingAccountInvoicesResponse> {\n const { data, error } = await this.client.GET(\"/billing/{billingAccountId}/invoices\", {\n params: { path: { billingAccountId } },\n });\n if (error) this.handleError(\"get billing account invoices\", error);\n return data!;\n }\n\n /**\n * Create a Stripe setup session for a new billing account.\n *\n * @param body - Setup session creation payload\n * @returns Setup session with redirect URL\n */\n async createSetupSession(body: CreateSetupSessionPayload): Promise<CreateSetupSessionResponse> {\n const { data, error } = await this.client.POST(\"/billing/create-setup-session\", {\n body,\n });\n if (error) this.handleError(\"create setup session\", error);\n return data!;\n }\n\n /**\n * Create a Stripe billing portal session.\n *\n * @param billingAccountId - The unique identifier of the billing account\n * @param body - Portal session creation payload\n * @returns Portal session with redirect URL\n */\n async createBillingPortalSession(billingAccountId: string, body: CreateBillingPortalSessionPayload): Promise<CreateBillingPortalSessionResponse> {\n const { data, error } = await this.client.POST(\"/billing/{billingAccountId}/create-billing-portal-session\", {\n params: { path: { billingAccountId } },\n body,\n });\n if (error) this.handleError(\"create billing portal session\", error);\n return data!;\n }\n\n /**\n * Get billing options for a project.\n *\n * @param projectId - The unique identifier of the project\n * @returns Billing options including current state and change options\n */\n async getBillingOptions(projectId: string): Promise<GetBillingOptionsResponse> {\n const { data, error } = await this.client.GET(\"/projects/{projectId}/get-billing-options\", {\n params: { path: { projectId } },\n });\n if (error) this.handleError(\"get billing options\", error);\n return data!;\n }\n\n /**\n * Set a billing account on a project.\n *\n * @param projectId - The unique identifier of the project\n * @param body - Billing account and state to set\n * @returns Success response\n */\n async setBillingAccount(projectId: string, body: SetBillingAccountPayload): Promise<SuccessResponse> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/set-billing-account\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"set billing account\", error);\n return data!;\n }\n\n /**\n * Cancel billing for a project.\n *\n * @param projectId - The unique identifier of the project\n * @returns Success response\n */\n async cancelBilling(projectId: string): Promise<SuccessResponse> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/cancel-billing\", {\n params: { path: { projectId } },\n });\n if (error) this.handleError(\"cancel billing\", error);\n return data!;\n }\n\n // ==================== API Activation ====================\n\n /**\n * Activate an API for the specified project.\n *\n * @param projectId - The unique identifier of the project\n * @param body - The API slug to activate\n * @returns Success response\n */\n async activateAPI(projectId: string, body: ActivateAPIPayload): Promise<SuccessResponse> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/activate-api\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"activate API\", error);\n return data!;\n }\n\n // ==================== Invoices ====================\n\n /**\n * Get all invoices for the current user, optionally filtered by ID.\n *\n * @param query - Optional query parameters for filtering by invoice IDs\n * @returns Array of invoices\n */\n async getInvoices(query?: GetInvoicesQuery): Promise<GetInvoicesResponse> {\n const { data, error } = await this.client.GET(\"/invoices\", {\n params: { query },\n });\n if (error) this.handleError(\"get invoices\", error);\n return data!;\n }\n\n /**\n * Get a preview of the current month's invoice for a project.\n *\n * @param projectId - The unique identifier of the project\n * @returns Invoice preview\n */\n async getInvoicePreview(projectId: string): Promise<GetInvoicePreviewResponse> {\n const { data, error } = await this.client.GET(\"/projects/{projectId}/preview-invoice\", {\n params: { path: { projectId } },\n });\n if (error) this.handleError(\"get invoice preview\", error);\n return data!;\n }\n\n // ==================== Access Keys ====================\n\n /**\n * Get a specific access key.\n *\n * @param accessKeyId - The unique identifier of the access key\n * @returns Access key details\n */\n async getAccessKey(accessKeyId: string): Promise<GetAccessKeyResponse> {\n const { data, error } = await this.client.GET(\"/odin-access-keys/{accessKeyId}\", {\n params: { path: { accessKeyId } },\n });\n if (error) this.handleError(\"get access key\", error);\n return data!;\n }\n\n /**\n * Create a new access key for a project.\n *\n * @param body - Access key creation payload\n * @returns Created access key (includes the key value only in this response)\n */\n async createAccessKey(body: CreateAccessKeyPayload): Promise<CreateAccessKeyResponse> {\n const { data, error } = await this.client.POST(\"/odin-access-keys/\", {\n body,\n });\n if (error) this.handleError(\"create access key\", error);\n return data!;\n }\n\n /**\n * Update an existing access key's name or description.\n *\n * @param accessKeyId - The unique identifier of the access key\n * @param body - Updated access key fields\n * @returns Success response\n */\n async editAccessKey(accessKeyId: string, body: EditAccessKeyPayload): Promise<SuccessResponse> {\n const { data, error } = await this.client.PUT(\"/odin-access-keys/{accessKeyId}\", {\n params: { path: { accessKeyId } },\n body,\n });\n if (error) this.handleError(\"edit access key\", error);\n return data!;\n }\n\n /**\n * Delete an access key. This operation is irreversible.\n *\n * @param accessKeyId - The unique identifier of the access key\n * @returns Success response\n */\n async deleteAccessKey(accessKeyId: string): Promise<SuccessResponse> {\n const { data, error } = await this.client.DELETE(\"/odin-access-keys/{accessKeyId}\", {\n params: { path: { accessKeyId } },\n });\n if (error) this.handleError(\"delete access key\", error);\n return data!;\n }\n\n // ==================== Project Members ====================\n\n /**\n * Add a user to a project with a specified role.\n *\n * @param projectId - The unique identifier of the project\n * @param body - User email and role\n * @returns The created user role\n */\n async addProjectMember(projectId: string, body: AddUserToProjectPayload): Promise<OdinUserRole> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/add-user-permission\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"add project member\", error);\n return data!;\n }\n\n /**\n * Revoke a user's permission from a project.\n *\n * @param projectId - The unique identifier of the project\n * @param body - The permission ID to revoke\n * @returns Success response\n */\n async deleteProjectMember(projectId: string, body: RevokeUserPayload): Promise<SuccessResponse> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/revoke-user-permission\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"delete project member\", error);\n return data!;\n }\n\n /**\n * Change a project member's role.\n *\n * @param projectId - The unique identifier of the project\n * @param body - The permission ID and new role\n * @returns Success response\n */\n async changeMemberRole(projectId: string, body: ChangeUserRolePayload): Promise<SuccessResponse> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/change-user-role\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"change member role\", error);\n return data!;\n }\n\n // ==================== Tokens & Secrets ====================\n\n /**\n * Create an ODIN access token for a project.\n *\n * @param projectId - The unique identifier of the project\n * @param body - Token creation payload\n * @returns The created token\n */\n async createAccessToken(projectId: string, body: CreateTokenPayload): Promise<CreateAccessTokenResponse> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/create-token\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"create access token\", error);\n return data!;\n }\n\n /**\n * Revoke the secret for a project.\n *\n * @param projectId - The unique identifier of the project\n * @returns Updated project with new secret\n */\n async revokeSecret(projectId: string): Promise<PaymentProject> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/revoke-secret\", {\n params: { path: { projectId } },\n });\n if (error) this.handleError(\"revoke secret\", error);\n return data!;\n }\n\n // ==================== Resource Package Pricing ====================\n\n /**\n * Get the price for a single resource package in a specific region.\n *\n * @param projectId - The unique identifier of the project\n * @param body - Resource package, region, and quantity\n * @returns Price information\n */\n async getResourcePackagePrice(projectId: string, body: ResourcePackagePricePayload): Promise<ResourcePackagePrice> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/resource-package-price\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"get resource package price\", error);\n return data!;\n }\n\n /**\n * Get prices for multiple resource packages in a specific region.\n *\n * @param projectId - The unique identifier of the project\n * @param body - Resource package IDs, region, and quantity\n * @returns Array of price information\n */\n async getResourcePackagePrices(projectId: string, body: ResourcePackagePricesPayload): Promise<ResourcePackagePrice[]> {\n const { data, error } = await this.client.POST(\"/projects/{projectId}/resource-package-prices\", {\n params: { path: { projectId } },\n body,\n });\n if (error) this.handleError(\"get resource package prices\", error);\n return data!;\n }\n}\n\nexport default PaymentClient;\n"]}