This commit is contained in:
John Yeo
2026-02-18 16:24:19 +00:00
parent 1d7c22203c
commit e8366d22ea
849 changed files with 53574 additions and 8703 deletions

View File

@@ -4,13 +4,7 @@ alwaysApply: true
# SDK Generation Pipeline
This guide explains the complete SDK generation pipeline from Zod schemas to React hooks.
## Pipeline Overview
```
Zod Schemas → ORPC Contracts → OpenAPI Spec → Speakeasy SDKs → autumn-js Wrapper → React Hooks
```
Run `bun api` from root to execute the full pipeline.
@@ -20,27 +14,9 @@ Run `bun api` from root to execute the full pipeline.
**Location:** `shared/api/`
Schemas define request/response shapes with field descriptions and internal field markers.
### Key Patterns
- Use `.describe()` for field descriptions that appear in API docs
- Use `.meta({ internal: true })` to mark fields that should be stripped from the public OpenAPI spec
- Use `.meta({ id: "SchemaName" })` for schema registration in OpenAPI components
### Example
```typescript
// shared/api/customers/crud/createCustomerParams.ts
export const CreateCustomerParamsV0Schema = z.object({
id: CustomerIdSchema.optional().nullable(),
name: z.string().optional().describe("Customer display name"),
// Internal fields - stripped from public API
entity_id: z.string().optional().meta({ internal: true }),
with_autumn_id: z.boolean().default(false).meta({ internal: true }),
});
```
- Use `.describe()` for field descriptions in API docs
- Use `.meta({ internal: true })` for fields stripped from public OpenAPI spec
- Use `.meta({ id: "SchemaName" })` for schema registration
---
@@ -48,50 +24,9 @@ export const CreateCustomerParamsV0Schema = z.object({
**Location:** `packages/openapi/v2.1/contracts/`
Uses `@orpc/contract` to define route contracts that reference Zod schemas.
Each contract defines: `method`, `path`, `operationId`, `tags`, `input`, `output`.
### Contract Structure
Each contract defines:
- `method`: HTTP method (API is transitioning to RPC-style, so all POST)
- `path`: Route path (e.g., `/v1/customers.getOrCreate`)
- `operationId`: Unique operation identifier for SDK method naming
- `tags`: Grouping for docs
- `input`: Request body schema (with `.meta()` for examples)
- `output`: Response schema
### Example
```typescript
// packages/openapi/v2.1/contracts/customersContract.ts
export const getOrCreateCustomerContract = oc
.route({
method: "POST",
path: "/v1/customers.getOrCreate",
operationId: "getOrCreate",
tags: ["customers"],
description: getOrCreateCustomerJsDoc,
})
.input(
CreateCustomerParamsV1Schema.meta({
title: "GetOrCreateCustomerParams",
examples: [{ customer_id: "cus_123", name: "John Doe" }],
}),
)
.output(ApiCustomerV5Schema);
```
### Router Aggregation
All contracts are aggregated in `packages/openapi/v2.1/contracts/index.ts`:
```typescript
export const v2_1ContractRouter = oc.router({
getOrCreateCustomer: getOrCreateCustomerContract,
listPlans: listPlansContract,
attach: attachContract,
});
```
All contracts aggregated in `packages/openapi/v2.1/contracts/index.ts`.
---
@@ -99,29 +34,7 @@ export const v2_1ContractRouter = oc.router({
**Entry point:** `packages/openapi/v2.1/openapi2.1.ts`
### Step 3a: Register Internal Schemas
`packages/openapi/utils/registerInternalSchemas.ts` recursively walks Zod schemas and registers any with `.meta({ internal: true })` in the JSON_SCHEMA_INPUT_REGISTRY with `x-internal: true`. Call this for each schema that may contain internal fields.
### Step 3b: Generate via ORPC
Uses `@orpc/openapi` `OpenAPIGenerator` with `ZodToJsonSchemaConverter` to produce the raw OpenAPI document from the contract router.
### Step 3c: Apply Speakeasy Settings
`packages/openapi/utils/openapiTransform/applySpeakeasySettings.ts`:
- Adds `secretKey` bearer auth security scheme
- Configures `x-speakeasy-globals` with hidden `x-api-version` header parameter (defaults to "2.1")
### Step 3d: Inject Global Header Parameters
`packages/openapi/utils/openapiTransform/injectGlobalHeaderParameters.ts` adds the `x-api-version` header to every operation. This header is hidden in the SDK (users don't need to set it) but automatically sent with every request.
Server parses this in `server/src/honoMiddlewares/apiVersionMiddleware.ts` to determine API version for response formatting.
### Step 3e: Remove Internal Fields
`packages/openapi/utils/openapiTransform/removeInternalFields.ts` strips fields/parameters marked with `x-internal: true` or `internal: true` from the final spec. This ensures internal fields don't appear in the public API documentation or generated SDKs.
Steps: Register internal schemas → Generate via ORPC → Apply Speakeasy settings → Inject global headers → Remove internal fields.
---
@@ -129,158 +42,119 @@ Server parses this in `server/src/honoMiddlewares/apiVersionMiddleware.ts` to de
**Entry point:** `packages/openapi/api.ts`
### Step 4a: Generate SDKs in Parallel
`packages/openapi/utils/sdkGeneration/generateSdks.ts` runs Speakeasy CLI for both targets:
- **TypeScript:** `bunx speakeasy run -t autumn` → `packages/sdk/`
- **Python:** `bunx speakeasy run -t autumn-python` → `others/python-sdk/`
Speakeasy config lives in `packages/sdk/.speakeasy/workflow.yaml` and `gen.yaml`.
### Step 4b: Patch Python SDK
`packages/openapi/utils/sdkGeneration/patchPythonSdk.ts` fixes a Speakeasy bug where `get_global_from_env` returns `None` and overrides Pydantic defaults for `x-api-version`. This ensures the default version header works correctly.
### Step 4c: Merge Code Samples
`packages/openapi/utils/sdkGeneration/mergeCodeSamples.ts` applies Speakeasy overlay files (`.speakeasy/code-samples.overlay.yaml`) to add TypeScript and Python code samples to the OpenAPI spec used for documentation.
---
## 5. Mintlify Documentation Transform
## 5. autumn-js Architecture
**Location:** `packages/openapi/utils/mintlifyTransform/`
**Location:** `packages/autumn-js/src/`
### Step 5a: Transform OpenAPI
### Directory Structure
- **Strip JSDoc tags:** Removes `@example`, `@deprecated`, etc. from descriptions for cleaner docs
- **Transform code samples:** Converts Speakeasy SDK format to cleaner autumn-js format (simpler imports like `import { Autumn } from 'autumn-js'`, removes async wrappers and console.log)
- **Copy schema examples:** Moves examples from schema level to response content level for Mintlify rendering
### Step 5b: Generate API Reference MDX
`packages/openapi/utils/apiReferenceGenerator/` parses the OpenAPI spec and generates `DynamicParamField`/`DynamicResponseField` components. These enable dynamic field switching in Mintlify docs (showing different parameter descriptions based on context).
---
## 6. autumn-js Wrapper Layer
**Location:** `packages/autumn-js/`
The autumn-js package wraps the generated SDK and provides framework integrations.
### 6a: Backend Router
`packages/autumn-js/src/libraries/backend/routes/backendRouter.ts` creates pass-through routes that users mount on their backend (e.g., `/api/autumn/*`).
**Route groups:** customers, billing, entities, referrals, products, gen (general)
**Pattern:** Route handlers use `withAuth` to inject identity and call the SDK:
```typescript
export const handleGetOrCreateCustomer = withAuth({
fn: async ({ autumn, customerId, customerData, body }) => {
return await autumn.customers.getOrCreate({
customerId,
...customerData,
...body,
});
},
});
```
packages/autumn-js/src/
├── backend/ # Server-side
│ ├── adapters/ # Framework adapters (hono.ts, next.ts)
│ └── core/
│ ├── handlers/ # Request processing
│ │ ├── coreHandler.ts # Main handler factory
│ │ ├── executeRoute.ts # Route execution logic
│ │ └── resolveIdentity.ts
│ ├── routes/
│ │ ├── defaultRoutes.ts # Route definitions
│ │ └── routeBuilder.ts # rou3-based router
│ ├── types/ # Type definitions
│ └── utils/ # backendRes, secretKeyCheck
├── react/ # Client-side
│ ├── client/
│ │ ├── AutumnClient.ts # Client factory
│ │ └── internal/httpClient.ts
│ ├── hooks/ # useCustomer, useListPlans
│ └── AutumnContext.tsx # React context provider
├── sdk/ # Re-exports from @useautumn/sdk
└── utils/ # Shared utilities
```
**Response format:** `packages/autumn-js/src/libraries/backend/utils/backendRes.ts` wraps responses in a consistent structure with `{ statusCode, body }`. Errors include `{ message, code, statusCode, details }` for frontend console logging.
### Backend: Route Definitions
### 6b: React Client
Routes defined in `defaultRoutes.ts` using `RouteDefinition`:
`packages/autumn-js/src/libraries/react/client/ReactAutumnClient.tsx` mirrors the SDK interface but routes through the mounted backend routes.
```typescript
type RouteDefinition = {
route: string; // RPC-style name: "customers.get_or_create"
sdkMethod: (autumn, args) => Promise<any>;
inject?: { customerId?: boolean; customerData?: boolean };
customHandler?: CustomHandlerFn; // For special logic
requireCustomer?: boolean; // Default: true
};
```
**CORS Detection:** The client auto-detects CORS credential support:
1. `detectCors()` makes test requests to `/api/autumn/cors` with and without credentials
2. `shouldIncludeCredentials()` caches the result and logs a warning suggesting users set `includeCredentials` explicitly
3. Users can override with the `includeCredentials` prop in `AutumnProvider`
Standard routes use `inject` to auto-add identity fields. Use `customHandler` for complex logic (e.g., `customers.get_or_create` handles `errorOnNotFound`).
**Client methods:** `attach`, `checkout`, `cancel`, `check`, `track`, `openBillingPortal`, `setupPayment`, `query`, plus namespaced methods for `customers`, `entities`, `referrals`, `products`.
### Backend: Framework Adapters
### 6c: React Hooks
Adapters in `backend/adapters/` convert framework requests to `UnifiedRequest`:
Hooks like `packages/autumn-js/src/libraries/react/hooks/useCustomer.tsx`:
- Use SWR for data fetching with automatic caching
- Accept `expand`, `errorOnNotFound`, and `swrConfig` params
- Return `{ customer, isLoading, error, refetch }` plus SDK action methods
- Get client from `AutumnContext` or accept a `client` prop directly
```typescript
type UnifiedRequest = {
method: string;
path: string;
body: unknown;
raw: unknown; // Original request for identify()
};
```
### React Client
`AutumnClient.ts` creates a client with namespaced methods that call backend routes:
```typescript
const client = createAutumnClient({ baseUrl: "/api/autumn" });
// client.customers.getOrCreate(), client.billing.attach(), client.plans.list()
```
### React Hooks
Hooks use TanStack Query with consistent patterns:
```typescript
export const useCustomer = (params: UseCustomerParams = {}) => {
const client = useAutumnClient();
const { errorOnNotFound, queryOptions, ...sdkParams } = params;
return useQuery<Customer | null, ClientError>({
queryKey: ["autumn", "customer", sdkParams],
queryFn: async () => {
const response = await client.customers.getOrCreate({...});
if (response.error) throw response.error;
return response.data;
},
...queryOptions,
});
};
```
---
## 7. Framework Integrations
### Better Auth Plugin
`packages/autumn-js/src/libraries/backend/better-auth.ts` is a `BetterAuthPlugin` that:
- Mounts Autumn routes under `/api/auth/autumn/*`
- Extracts identity from Better Auth session
- Supports `customerScope: "user" | "organization" | "user_and_organization"`
- Auto-maps user/org to `customerId` and `customerData`
### Convex Client
`packages/autumn-js/src/libraries/react/client/ConvexAutumnClient.tsx`:
- Implements `IAutumnClient` interface
- Routes through Convex actions instead of HTTP (`convex.action()`)
- Stubs HTTP methods (`post`, `get`, etc.) with errors
- Same method signatures as `AutumnClient` for drop-in replacement
---
## 8. Testing (sdk-test)
## 6. Testing (sdk-test)
**Location:** `apps/sdk-test/`
### Scenario Pattern
Each integration is tested via scenario pages organized by provider:
- `scenarios/core/` - Default HTTP provider
- `scenarios/better-auth/` - Better Auth integration
- `scenarios/convex/` - Convex integration
### Page Structure
Each scenario page follows a consistent pattern:
1. **Hook params panel:** Exact params passed to the hook
2. **Hook state panel:** Loading, error, lastUpdatedAt
3. **Payload viewer:** Customer/entity data returned
4. **Action controls:** Refetch, etc.
### Scenario Registry
`apps/sdk-test/lib/scenarios.ts` tracks all scenarios with status:
- `ready` - Implemented and working
- `wip` - Work in progress
- `planned` - Not yet implemented
Scenario pages organized by provider: `scenarios/core/`, `scenarios/better-auth/`, `scenarios/convex/`.
---
## Source of Truth Rules
## Adding a New Route
1. **API behavior starts at Zod schemas and contracts**, not generated code
2. **Never hand-edit** `packages/sdk/src/**` - regeneration will overwrite
3. **If SDK shapes are wrong**, fix schemas/contracts first, then regenerate
4. **Keep backend routes aligned** with generated SDK operation models
---
## Required Change Workflow
When adding or changing SDK-backed features:
1. **Update Zod schemas** in `shared/api/` (use `.meta({ internal: true })` for internal fields)
2. **Add/update ORPC contract** in `packages/openapi/v2.1/contracts/`
3. **Add contract to router** in `packages/openapi/v2.1/contracts/index.ts`
4. **Regenerate** via `bun api` from root
5. **Wire backend route** in `autumn-js` if needed
6. **Wire React hook method** if needed
7. **Add scenario test coverage** in `apps/sdk-test/`
1. **Add contract** in `packages/openapi/v2.1/contracts/`
2. **Add to router** in `packages/openapi/v2.1/contracts/index.ts`
3. **Regenerate** via `bun api`
4. **Add route definition** in `defaultRoutes.ts`
5. **Add client method** in `AutumnClient.ts`
6. **Add hook** in `react/hooks/` if needed
7. **Add scenario test** in `apps/sdk-test/`
---
@@ -290,10 +164,9 @@ When adding or changing SDK-backed features:
|---------|------|
| Zod schemas | `shared/api/` |
| ORPC contracts | `packages/openapi/v2.1/contracts/` |
| OpenAPI generation | `packages/openapi/v2.1/openapi2.1.ts` |
| Pipeline entry | `packages/openapi/api.ts` |
| Generated TS SDK | `packages/sdk/` |
| Generated Python SDK | `others/python-sdk/` |
| autumn-js backend | `packages/autumn-js/src/libraries/backend/` |
| autumn-js react | `packages/autumn-js/src/libraries/react/` |
| Backend core handler | `packages/autumn-js/src/backend/core/handlers/coreHandler.ts` |
| Route definitions | `packages/autumn-js/src/backend/core/routes/defaultRoutes.ts` |
| React client | `packages/autumn-js/src/react/client/AutumnClient.ts` |
| React hooks | `packages/autumn-js/src/react/hooks/` |
| SDK tests | `apps/sdk-test/` |

View File

@@ -1,5 +1,8 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"python.defaultInterpreterPath": "others/python-test/.venv/bin/python",
"python.analysis.extraPaths": ["others/python-sdk/src"],
"python.autoComplete.extraPaths": ["others/python-sdk/src"],
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"editor.formatOnPaste": true,

View File

@@ -1,6 +1,6 @@
---
title: "Get or Create Customer"
openapi: "openapi POST /v1/customers.getOrCreate"
openapi: "openapi POST /v1/customers.get_or_create"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";

View File

@@ -0,0 +1,390 @@
---
title: "Balances Check"
openapi: "openapi POST /v1/balances.check"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
### Body Parameters
<DynamicParamField body="customer_id" type="string" required>
ID which you provided when creating the customer
</DynamicParamField>
<DynamicParamField body="feature_id" type="string" />
<DynamicParamField body="entity_id" type="string">
If using entity balances (eg, seats), the entity ID to check access for.
</DynamicParamField>
<DynamicParamField body="required_balance" type="number">
If you know the amount of the feature the end user is consuming in advance. If their balance is below this quantity, allowed will be false.
</DynamicParamField>
<DynamicParamField body="properties" type="object" />
<DynamicParamField body="send_event" type="boolean">
If true, a usage event will be recorded together with checking access. The required_balance field will be used as the usage value.
</DynamicParamField>
<DynamicParamField body="with_preview" type="boolean">
If true, the response will include a preview object, which can be used to display information such as a paywall or upgrade confirmation.
</DynamicParamField>
<DynamicParamField body="product_id" type="string" />
<DynamicParamField body="required_quantity" type="number" />
### Response
<DynamicResponseField name="allowed" type="boolean" />
<DynamicResponseField name="customer_id" type="string" />
<DynamicResponseField name="entity_id" type="string | null" />
<DynamicResponseField name="required_balance" type="number" />
<DynamicResponseField name="balance" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="object" type="any" />
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="feature" type="object">
<Expandable title="properties">
<DynamicResponseField name="id" type="string" />
<DynamicResponseField name="name" type="string" />
<DynamicResponseField name="type" type="'boolean' | 'metered' | 'credit_system'" />
<DynamicResponseField name="consumable" type="boolean" />
<DynamicResponseField name="event_names" type="string[]" />
<DynamicResponseField name="credit_schema" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="metered_feature_id" type="string" />
<DynamicResponseField name="credit_cost" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="display" type="object">
<Expandable title="properties">
<DynamicResponseField name="singular" type="string | null" />
<DynamicResponseField name="plural" type="string | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="archived" type="boolean" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="granted" type="number" />
<DynamicResponseField name="remaining" type="number" />
<DynamicResponseField name="usage" type="number" />
<DynamicResponseField name="unlimited" type="boolean" />
<DynamicResponseField name="overage_allowed" type="boolean" />
<DynamicResponseField name="max_purchase" type="number | null" />
<DynamicResponseField name="next_reset_at" type="number | null" />
<DynamicResponseField name="breakdown" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="object" type="any" />
<DynamicResponseField name="id" type="string" />
<DynamicResponseField name="plan_id" type="string | null" />
<DynamicResponseField name="included_grant" type="number" />
<DynamicResponseField name="prepaid_grant" type="number" />
<DynamicResponseField name="remaining" type="number" />
<DynamicResponseField name="usage" type="number" />
<DynamicResponseField name="unlimited" type="boolean" />
<DynamicResponseField name="reset" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="resets_at" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="tiers" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="to" type="number" />
<DynamicResponseField name="amount" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="billing_units" type="number" />
<DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'" />
<DynamicResponseField name="max_purchase" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="expires_at" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rollovers" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="balance" type="number" />
<DynamicResponseField name="expires_at" type="number" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="preview" type="object">
<Expandable title="properties">
<DynamicResponseField name="scenario" type="'usage_limit' | 'feature_flag'" />
<DynamicResponseField name="title" type="string" />
<DynamicResponseField name="message" type="string" />
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="feature_name" type="string" />
<DynamicResponseField name="products" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="id" type="string">
The ID of the product you set when creating the product
</DynamicResponseField>
<DynamicResponseField name="name" type="string">
The name of the product
</DynamicResponseField>
<DynamicResponseField name="group" type="string | null">
Product group which this product belongs to
</DynamicResponseField>
<DynamicResponseField name="env" type="'sandbox' | 'live'">
The environment of the product
</DynamicResponseField>
<DynamicResponseField name="is_add_on" type="boolean">
Whether the product is an add-on and can be purchased alongside other products
</DynamicResponseField>
<DynamicResponseField name="is_default" type="boolean">
Whether the product is the default product
</DynamicResponseField>
<DynamicResponseField name="archived" type="boolean">
Whether this product has been archived and is no longer available
</DynamicResponseField>
<DynamicResponseField name="version" type="number">
The current version of the product
</DynamicResponseField>
<DynamicResponseField name="created_at" type="number">
The timestamp of when the product was created in milliseconds since epoch
</DynamicResponseField>
<DynamicResponseField name="items" type="object[]">
Array of product items that define the product's features and pricing
<Expandable title="properties">
<DynamicResponseField name="type" type="'feature' | 'priced_feature' | 'price'">
The type of the product item
</DynamicResponseField>
<DynamicResponseField name="feature_id" type="string | null">
The feature ID of the product item. If the item is a fixed price, should be `null`
</DynamicResponseField>
<DynamicResponseField name="feature_type" type="'single_use' | 'continuous_use' | 'boolean' | 'static'">
Single use features are used once and then depleted, like API calls or credits. Continuous use features are those being used on an ongoing-basis, like storage or seats.
</DynamicResponseField>
<DynamicResponseField name="included_usage" type="number | null">
The amount of usage included for this feature.
</DynamicResponseField>
<DynamicResponseField name="interval" type="'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'">
The reset or billing interval of the product item. If null, feature will have no reset date, and if there's a price, it will be billed one-off.
</DynamicResponseField>
<DynamicResponseField name="interval_count" type="number | null">
The interval count of the product item.
</DynamicResponseField>
<DynamicResponseField name="price" type="number | null">
The price of the product item. Should be `null` if tiered pricing is set.
</DynamicResponseField>
<DynamicResponseField name="tiers" type="object[] | null">
Tiered pricing for the product item. Not applicable for fixed price items.
<Expandable title="properties">
<DynamicResponseField name="to" type="number">
The maximum amount of usage for this tier.
</DynamicResponseField>
<DynamicResponseField name="amount" type="number">
The price of the product item for this tier.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="usage_model" type="'prepaid' | 'pay_per_use'">
Whether the feature should be prepaid upfront or billed for how much they use end of billing period.
</DynamicResponseField>
<DynamicResponseField name="billing_units" type="number | null">
The amount per billing unit (eg. $9 / 250 units)
</DynamicResponseField>
<DynamicResponseField name="reset_usage_when_enabled" type="boolean | null">
Whether the usage should be reset when the product is enabled.
</DynamicResponseField>
<DynamicResponseField name="entity_feature_id" type="string | null">
The entity feature ID of the product item if applicable.
</DynamicResponseField>
<DynamicResponseField name="display" type="object | null">
The display of the product item.
<Expandable title="properties">
<DynamicResponseField name="primary_text" type="string" />
<DynamicResponseField name="secondary_text" type="string | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="quantity" type="number | null">
Used in customer context. Quantity of the feature the customer has prepaid for.
</DynamicResponseField>
<DynamicResponseField name="next_cycle_quantity" type="number | null">
Used in customer context. Quantity of the feature the customer will prepay for in the next cycle.
</DynamicResponseField>
<DynamicResponseField name="config" type="object | null">
Configuration for rollover and proration behavior of the feature.
<Expandable title="properties">
<DynamicResponseField name="rollover" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="max" type="number | null" />
<DynamicResponseField name="duration" type="'month' | 'forever'" />
<DynamicResponseField name="length" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" />
<DynamicResponseField name="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="free_trial" type="object | null">
Free trial configuration for this product, if available
<Expandable title="properties">
<DynamicResponseField name="duration" type="'day' | 'month' | 'year'">
The duration type of the free trial
</DynamicResponseField>
<DynamicResponseField name="length" type="number">
The length of the duration type specified
</DynamicResponseField>
<DynamicResponseField name="unique_fingerprint" type="boolean">
Whether the free trial is limited to one per customer fingerprint
</DynamicResponseField>
<DynamicResponseField name="card_required" type="boolean">
Whether the free trial requires a card. If false, the customer can attach the product without going through a checkout flow or having a card on file.
</DynamicResponseField>
<DynamicResponseField name="trial_available" type="boolean | null">
Used in customer context. Whether the free trial is available for the customer if they were to attach the product.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="base_variant_id" type="string | null">
ID of the base variant this product is derived from
</DynamicResponseField>
<DynamicResponseField name="scenario" type="'scheduled' | 'active' | 'new' | 'renew' | 'upgrade' | 'downgrade' | 'cancel' | 'expired' | 'past_due'">
Scenario for when this product is used in attach flows
</DynamicResponseField>
<DynamicResponseField name="properties" type="object">
<Expandable title="properties">
<DynamicResponseField name="is_free" type="boolean">
True if the product has no base price or usage prices
</DynamicResponseField>
<DynamicResponseField name="is_one_off" type="boolean">
True if the product only contains a one-time price
</DynamicResponseField>
<DynamicResponseField name="interval_group" type="string | null">
The billing interval group for recurring products (e.g., 'monthly', 'yearly')
</DynamicResponseField>
<DynamicResponseField name="has_trial" type="boolean | null">
True if the product includes a free trial
</DynamicResponseField>
<DynamicResponseField name="updateable" type="boolean | null">
True if the product can be updated after creation (only applicable if there are prepaid recurring prices)
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>

View File

@@ -0,0 +1,51 @@
---
title: "Balances Create"
openapi: "openapi POST /v1/balances.create"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
### Body Parameters
<DynamicParamField body="feature_id" type="string" required>
The feature ID to create the balance for
</DynamicParamField>
<DynamicParamField body="customer_id" type="string" required>
The customer ID to assign the balance to
</DynamicParamField>
<DynamicParamField body="entity_id" type="string">
Entity ID for entity-scoped balances
</DynamicParamField>
<DynamicParamField body="included" type="number">
The initial balance amount to grant
</DynamicParamField>
<DynamicParamField body="unlimited" type="boolean">
Whether the balance is unlimited
</DynamicParamField>
<DynamicParamField body="reset" type="object">
Reset configuration for the balance
<Expandable title="properties">
<DynamicParamField body="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" required />
<DynamicParamField body="interval_count" type="number" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="expires_at" type="number">
Unix timestamp (milliseconds) when the balance expires
</DynamicParamField>
<DynamicParamField body="granted_balance" type="number" />
### Response
<DynamicResponseField name="success" type="boolean" />

View File

@@ -0,0 +1,180 @@
---
title: "Balances Track"
openapi: "openapi POST /v1/balances.track"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
### Body Parameters
<DynamicParamField body="customer_id" type="string" required>
ID which you provided when creating the customer
</DynamicParamField>
<DynamicParamField body="feature_id" type="string">
ID of the feature to track usage for. Required if event_name is not provided. Use this for direct feature tracking.
</DynamicParamField>
<DynamicParamField body="event_name" type="string">
An [event name](/features/tracking-usage#using-event-names) can be used in place of feature_id. This can be used if multiple features are tracked in the same event.
</DynamicParamField>
<DynamicParamField body="value" type="number">
The amount of usage to record. Defaults to 1. Can be negative to increase the balance (e.g., when removing a seat).
</DynamicParamField>
<DynamicParamField body="properties" type="object">
Additional properties to attach to this usage event.
</DynamicParamField>
<DynamicParamField body="idempotency_key" type="string">
Unique key to prevent duplicate event recording. Use this to safely retry requests without creating duplicate usage records.
</DynamicParamField>
<DynamicParamField body="entity_id" type="string">
If using [entity balances](/features/feature-entities) (eg, seats), the entity ID to track usage for.
</DynamicParamField>
### Response
<DynamicResponseField name="customer_id" type="string">
The ID of the customer
</DynamicResponseField>
<DynamicResponseField name="entity_id" type="string">
The ID of the entity (if provided)
</DynamicResponseField>
<DynamicResponseField name="event_name" type="string">
The name of the event
</DynamicResponseField>
<DynamicResponseField name="value" type="number" />
<DynamicResponseField name="balance" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="object" type="any" />
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="feature" type="object">
<Expandable title="properties">
<DynamicResponseField name="id" type="string" />
<DynamicResponseField name="name" type="string" />
<DynamicResponseField name="type" type="'boolean' | 'metered' | 'credit_system'" />
<DynamicResponseField name="consumable" type="boolean" />
<DynamicResponseField name="event_names" type="string[]" />
<DynamicResponseField name="credit_schema" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="metered_feature_id" type="string" />
<DynamicResponseField name="credit_cost" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="display" type="object">
<Expandable title="properties">
<DynamicResponseField name="singular" type="string | null" />
<DynamicResponseField name="plural" type="string | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="archived" type="boolean" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="granted" type="number" />
<DynamicResponseField name="remaining" type="number" />
<DynamicResponseField name="usage" type="number" />
<DynamicResponseField name="unlimited" type="boolean" />
<DynamicResponseField name="overage_allowed" type="boolean" />
<DynamicResponseField name="max_purchase" type="number | null" />
<DynamicResponseField name="next_reset_at" type="number | null" />
<DynamicResponseField name="breakdown" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="object" type="any" />
<DynamicResponseField name="id" type="string" />
<DynamicResponseField name="plan_id" type="string | null" />
<DynamicResponseField name="included_grant" type="number" />
<DynamicResponseField name="prepaid_grant" type="number" />
<DynamicResponseField name="remaining" type="number" />
<DynamicResponseField name="usage" type="number" />
<DynamicResponseField name="unlimited" type="boolean" />
<DynamicResponseField name="reset" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="resets_at" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="tiers" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="to" type="number" />
<DynamicResponseField name="amount" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="billing_units" type="number" />
<DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'" />
<DynamicResponseField name="max_purchase" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="expires_at" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rollovers" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="balance" type="number" />
<DynamicResponseField name="expires_at" type="number" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="balances" type="object" />

View File

@@ -0,0 +1,45 @@
---
title: "Balances Update"
openapi: "openapi POST /v1/balances.update"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
### Body Parameters
<DynamicParamField body="customer_id" type="string" required>
The ID of the customer.
</DynamicParamField>
<DynamicParamField body="entity_id" type="string">
The ID of the entity to update balance for (if using entity balances).
</DynamicParamField>
<DynamicParamField body="feature_id" type="string" required>
The ID of the feature to update balance for.
</DynamicParamField>
<DynamicParamField body="current_balance" type="number">
The new balance value to set.
</DynamicParamField>
<DynamicParamField body="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'">
The interval to update balance for.
</DynamicParamField>
<DynamicParamField body="granted_balance" type="number" />
<DynamicParamField body="usage" type="number" />
<DynamicParamField body="customer_entitlement_id" type="string" />
<DynamicParamField body="next_reset_at" type="number" />
<DynamicParamField body="add_to_balance" type="number" />
### Response
<DynamicResponseField name="success" type="boolean" />

View File

@@ -0,0 +1,183 @@
---
title: "Billing Attach"
openapi: "openapi POST /v1/billing.attach"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
### Body Parameters
<DynamicParamField body="customer_id" type="string" required>
The ID of the customer to attach the plan to.
</DynamicParamField>
<DynamicParamField body="entity_id" type="string | null">
The ID of the entity to attach the plan to.
</DynamicParamField>
<DynamicParamField body="feature_quantities" type="object[] | null">
If this plan contains prepaid features, use this field to specify the quantity of each prepaid feature. This quantity includes the included amount and billing units defined when setting up the plan.
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required />
<DynamicParamField body="quantity" type="number" />
<DynamicParamField body="adjustable" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="version" type="number" />
<DynamicParamField body="free_trial" type="object | null">
<Expandable title="properties">
<DynamicParamField body="duration_length" type="number" required />
<DynamicParamField body="duration_type" type="'day' | 'month' | 'year'" />
<DynamicParamField body="card_required" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="customize" type="object">
<Expandable title="properties">
<DynamicParamField body="price" type="object | null">
<Expandable title="properties">
<DynamicParamField body="amount" type="number" required />
<DynamicParamField body="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" required />
<DynamicParamField body="interval_count" type="number" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="items" type="object[]">
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required />
<DynamicParamField body="included" type="number" />
<DynamicParamField body="unlimited" type="boolean" />
<DynamicParamField body="reset" type="object">
<Expandable title="properties">
<DynamicParamField body="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" required />
<DynamicParamField body="interval_count" type="number" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="price" type="object">
<Expandable title="properties">
<DynamicParamField body="amount" type="number" />
<DynamicParamField body="tiers" type="object[]">
<Expandable title="properties">
<DynamicParamField body="to" type="number" required />
<DynamicParamField body="amount" type="number" required />
</Expandable>
</DynamicParamField>
<DynamicParamField body="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" required />
<DynamicParamField body="interval_count" type="number" />
<DynamicParamField body="billing_units" type="number" />
<DynamicParamField body="billing_method" type="'prepaid' | 'usage_based'" required />
<DynamicParamField body="max_purchase" type="number" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="proration" type="object">
<Expandable title="properties">
<DynamicParamField body="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" required />
<DynamicParamField body="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" required />
</Expandable>
</DynamicParamField>
<DynamicParamField body="rollover" type="object">
<Expandable title="properties">
<DynamicParamField body="max" type="number" />
<DynamicParamField body="expiry_duration_type" type="'month' | 'forever'" required />
<DynamicParamField body="expiry_duration_length" type="number" />
</Expandable>
</DynamicParamField>
</Expandable>
</DynamicParamField>
</Expandable>
</DynamicParamField>
<DynamicParamField body="plan_id" type="string" required />
<DynamicParamField body="invoice_mode" type="object">
<Expandable title="properties">
<DynamicParamField body="enabled" type="boolean" required />
<DynamicParamField body="enable_product_immediately" type="boolean" />
<DynamicParamField body="finalize_invoice" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="discounts" type="object[]" />
<DynamicParamField body="redirect_mode" type="'always' | 'if_required' | 'never'" />
<DynamicParamField body="success_url" type="string" />
<DynamicParamField body="new_billing_subscription" type="boolean" />
<DynamicParamField body="plan_schedule" type="'immediate' | 'end_of_cycle'" />
<DynamicParamField body="billing_behavior" type="'prorate_immediately' | 'next_cycle_only'" />
### Response
<DynamicResponseField name="customer_id" type="string" />
<DynamicResponseField name="entity_id" type="string" />
<DynamicResponseField name="invoice" type="object">
<Expandable title="properties">
<DynamicResponseField name="status" type="string | null" />
<DynamicResponseField name="stripe_id" type="string" />
<DynamicResponseField name="total" type="number" />
<DynamicResponseField name="currency" type="string" />
<DynamicResponseField name="hosted_invoice_url" type="string | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="payment_url" type="string | null" />
<DynamicResponseField name="required_action" type="object">
<Expandable title="properties">
<DynamicResponseField name="code" type="'3ds_required' | 'payment_method_required' | 'payment_failed'" />
<DynamicResponseField name="reason" type="string" />
</Expandable>
</DynamicResponseField>

View File

@@ -0,0 +1,691 @@
---
title: "Billing Preview Attach"
openapi: "openapi POST /v1/billing.preview_attach"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
### Body Parameters
<DynamicParamField body="customer_id" type="string" required>
The ID of the customer to attach the plan to.
</DynamicParamField>
<DynamicParamField body="entity_id" type="string | null">
The ID of the entity to attach the plan to.
</DynamicParamField>
<DynamicParamField body="feature_quantities" type="object[] | null">
If this plan contains prepaid features, use this field to specify the quantity of each prepaid feature. This quantity includes the included amount and billing units defined when setting up the plan.
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required />
<DynamicParamField body="quantity" type="number" />
<DynamicParamField body="adjustable" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="version" type="number" />
<DynamicParamField body="free_trial" type="object | null">
<Expandable title="properties">
<DynamicParamField body="duration_length" type="number" required />
<DynamicParamField body="duration_type" type="'day' | 'month' | 'year'" />
<DynamicParamField body="card_required" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="customize" type="object">
<Expandable title="properties">
<DynamicParamField body="price" type="object | null">
<Expandable title="properties">
<DynamicParamField body="amount" type="number" required />
<DynamicParamField body="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" required />
<DynamicParamField body="interval_count" type="number" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="items" type="object[]">
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required />
<DynamicParamField body="included" type="number" />
<DynamicParamField body="unlimited" type="boolean" />
<DynamicParamField body="reset" type="object">
<Expandable title="properties">
<DynamicParamField body="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" required />
<DynamicParamField body="interval_count" type="number" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="price" type="object">
<Expandable title="properties">
<DynamicParamField body="amount" type="number" />
<DynamicParamField body="tiers" type="object[]">
<Expandable title="properties">
<DynamicParamField body="to" type="number" required />
<DynamicParamField body="amount" type="number" required />
</Expandable>
</DynamicParamField>
<DynamicParamField body="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" required />
<DynamicParamField body="interval_count" type="number" />
<DynamicParamField body="billing_units" type="number" />
<DynamicParamField body="billing_method" type="'prepaid' | 'usage_based'" required />
<DynamicParamField body="max_purchase" type="number" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="proration" type="object">
<Expandable title="properties">
<DynamicParamField body="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" required />
<DynamicParamField body="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" required />
</Expandable>
</DynamicParamField>
<DynamicParamField body="rollover" type="object">
<Expandable title="properties">
<DynamicParamField body="max" type="number" />
<DynamicParamField body="expiry_duration_type" type="'month' | 'forever'" required />
<DynamicParamField body="expiry_duration_length" type="number" />
</Expandable>
</DynamicParamField>
</Expandable>
</DynamicParamField>
</Expandable>
</DynamicParamField>
<DynamicParamField body="plan_id" type="string" required />
<DynamicParamField body="invoice_mode" type="object">
<Expandable title="properties">
<DynamicParamField body="enabled" type="boolean" required />
<DynamicParamField body="enable_product_immediately" type="boolean" />
<DynamicParamField body="finalize_invoice" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="discounts" type="object[]" />
<DynamicParamField body="redirect_mode" type="'always' | 'if_required' | 'never'" />
<DynamicParamField body="success_url" type="string" />
<DynamicParamField body="new_billing_subscription" type="boolean" />
<DynamicParamField body="plan_schedule" type="'immediate' | 'end_of_cycle'" />
<DynamicParamField body="billing_behavior" type="'prorate_immediately' | 'next_cycle_only'" />
### Response
<DynamicResponseField name="customer_id" type="string" />
<DynamicResponseField name="line_items" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="title" type="string" />
<DynamicResponseField name="description" type="string" />
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="discounts" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="amountOff" type="number" />
<DynamicResponseField name="percentOff" type="number" />
<DynamicResponseField name="stripeCouponId" type="string" />
<DynamicResponseField name="couponName" type="string" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="is_base" type="boolean" />
<DynamicResponseField name="total_quantity" type="number" />
<DynamicResponseField name="paid_quantity" type="number" />
<DynamicResponseField name="plan_id" type="string" />
<DynamicResponseField name="deferred_for_trial" type="boolean" />
<DynamicResponseField name="effective_period" type="object">
<Expandable title="properties">
<DynamicResponseField name="start" type="number" />
<DynamicResponseField name="end" type="number" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="total" type="number" />
<DynamicResponseField name="currency" type="string" />
<DynamicResponseField name="period_start" type="number" />
<DynamicResponseField name="period_end" type="number" />
<DynamicResponseField name="credit" type="object">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="description" type="string" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="next_cycle" type="object">
<Expandable title="properties">
<DynamicResponseField name="starts_at" type="number" />
<DynamicResponseField name="total" type="number" />
<DynamicResponseField name="line_items" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="title" type="string" />
<DynamicResponseField name="description" type="string" />
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="discounts" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="amountOff" type="number" />
<DynamicResponseField name="percentOff" type="number" />
<DynamicResponseField name="stripeCouponId" type="string" />
<DynamicResponseField name="couponName" type="string" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="is_base" type="boolean" />
<DynamicResponseField name="total_quantity" type="number" />
<DynamicResponseField name="paid_quantity" type="number" />
<DynamicResponseField name="plan_id" type="string" />
<DynamicResponseField name="deferred_for_trial" type="boolean" />
<DynamicResponseField name="effective_period" type="object">
<Expandable title="properties">
<DynamicResponseField name="start" type="number" />
<DynamicResponseField name="end" type="number" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="incoming" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="plan" type="object">
<Expandable title="properties">
<DynamicResponseField name="id" type="string" />
<DynamicResponseField name="name" type="string" />
<DynamicResponseField name="description" type="string | null" />
<DynamicResponseField name="group" type="string | null" />
<DynamicResponseField name="version" type="number" />
<DynamicResponseField name="add_on" type="boolean" />
<DynamicResponseField name="auto_enable" type="boolean" />
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="display" type="object">
<Expandable title="properties">
<DynamicResponseField name="primary_text" type="string" />
<DynamicResponseField name="secondary_text" type="string" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="items" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="feature" type="object">
<Expandable title="properties">
<DynamicResponseField name="id" type="string">
The ID of the feature, used to refer to it in other API calls like /track or /check.
</DynamicResponseField>
<DynamicResponseField name="name" type="string | null">
The name of the feature.
</DynamicResponseField>
<DynamicResponseField name="type" type="'static' | 'boolean' | 'single_use' | 'continuous_use' | 'credit_system'">
The type of the feature
</DynamicResponseField>
<DynamicResponseField name="display" type="object | null">
Singular and plural display names for the feature.
<Expandable title="properties">
<DynamicResponseField name="singular" type="string">
The singular display name for the feature.
</DynamicResponseField>
<DynamicResponseField name="plural" type="string">
The plural display name for the feature.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="credit_schema" type="object[] | null">
Credit cost schema for credit system features.
<Expandable title="properties">
<DynamicResponseField name="metered_feature_id" type="string">
The ID of the metered feature (should be a single_use feature).
</DynamicResponseField>
<DynamicResponseField name="credit_cost" type="number">
The credit cost of the metered feature.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="archived" type="boolean | null">
Whether or not the feature is archived.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="included" type="number" />
<DynamicResponseField name="unlimited" type="boolean" />
<DynamicResponseField name="reset" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="tiers" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="to" type="number" />
<DynamicResponseField name="amount" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="billing_units" type="number" />
<DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'" />
<DynamicResponseField name="max_purchase" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="display" type="object">
<Expandable title="properties">
<DynamicResponseField name="primary_text" type="string" />
<DynamicResponseField name="secondary_text" type="string" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rollover" type="object">
<Expandable title="properties">
<DynamicResponseField name="max" type="number | null" />
<DynamicResponseField name="expiry_duration_type" type="'month' | 'forever'" />
<DynamicResponseField name="expiry_duration_length" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="proration" type="object">
<Expandable title="properties">
<DynamicResponseField name="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" />
<DynamicResponseField name="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="free_trial" type="object">
<Expandable title="properties">
<DynamicResponseField name="duration_length" type="number" />
<DynamicResponseField name="duration_type" type="'day' | 'month' | 'year'" />
<DynamicResponseField name="card_required" type="boolean" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="created_at" type="number" />
<DynamicResponseField name="env" type="'sandbox' | 'live'" />
<DynamicResponseField name="archived" type="boolean" />
<DynamicResponseField name="base_variant_id" type="string | null" />
<DynamicResponseField name="customer_eligibility" type="object">
<Expandable title="properties">
<DynamicResponseField name="trial_available" type="boolean" />
<DynamicResponseField name="scenario" type="'scheduled' | 'active' | 'new' | 'renew' | 'upgrade' | 'downgrade' | 'cancel' | 'expired' | 'past_due'" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="feature_quantities" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="quantity" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="balances" type="object" />
<DynamicResponseField name="period_start" type="number" />
<DynamicResponseField name="period_end" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="outgoing" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="plan" type="object">
<Expandable title="properties">
<DynamicResponseField name="id" type="string" />
<DynamicResponseField name="name" type="string" />
<DynamicResponseField name="description" type="string | null" />
<DynamicResponseField name="group" type="string | null" />
<DynamicResponseField name="version" type="number" />
<DynamicResponseField name="add_on" type="boolean" />
<DynamicResponseField name="auto_enable" type="boolean" />
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="display" type="object">
<Expandable title="properties">
<DynamicResponseField name="primary_text" type="string" />
<DynamicResponseField name="secondary_text" type="string" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="items" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="feature" type="object">
<Expandable title="properties">
<DynamicResponseField name="id" type="string">
The ID of the feature, used to refer to it in other API calls like /track or /check.
</DynamicResponseField>
<DynamicResponseField name="name" type="string | null">
The name of the feature.
</DynamicResponseField>
<DynamicResponseField name="type" type="'static' | 'boolean' | 'single_use' | 'continuous_use' | 'credit_system'">
The type of the feature
</DynamicResponseField>
<DynamicResponseField name="display" type="object | null">
Singular and plural display names for the feature.
<Expandable title="properties">
<DynamicResponseField name="singular" type="string">
The singular display name for the feature.
</DynamicResponseField>
<DynamicResponseField name="plural" type="string">
The plural display name for the feature.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="credit_schema" type="object[] | null">
Credit cost schema for credit system features.
<Expandable title="properties">
<DynamicResponseField name="metered_feature_id" type="string">
The ID of the metered feature (should be a single_use feature).
</DynamicResponseField>
<DynamicResponseField name="credit_cost" type="number">
The credit cost of the metered feature.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="archived" type="boolean | null">
Whether or not the feature is archived.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="included" type="number" />
<DynamicResponseField name="unlimited" type="boolean" />
<DynamicResponseField name="reset" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="tiers" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="to" type="number" />
<DynamicResponseField name="amount" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="billing_units" type="number" />
<DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'" />
<DynamicResponseField name="max_purchase" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="display" type="object">
<Expandable title="properties">
<DynamicResponseField name="primary_text" type="string" />
<DynamicResponseField name="secondary_text" type="string" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rollover" type="object">
<Expandable title="properties">
<DynamicResponseField name="max" type="number | null" />
<DynamicResponseField name="expiry_duration_type" type="'month' | 'forever'" />
<DynamicResponseField name="expiry_duration_length" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="proration" type="object">
<Expandable title="properties">
<DynamicResponseField name="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" />
<DynamicResponseField name="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="free_trial" type="object">
<Expandable title="properties">
<DynamicResponseField name="duration_length" type="number" />
<DynamicResponseField name="duration_type" type="'day' | 'month' | 'year'" />
<DynamicResponseField name="card_required" type="boolean" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="created_at" type="number" />
<DynamicResponseField name="env" type="'sandbox' | 'live'" />
<DynamicResponseField name="archived" type="boolean" />
<DynamicResponseField name="base_variant_id" type="string | null" />
<DynamicResponseField name="customer_eligibility" type="object">
<Expandable title="properties">
<DynamicResponseField name="trial_available" type="boolean" />
<DynamicResponseField name="scenario" type="'scheduled' | 'active' | 'new' | 'renew' | 'upgrade' | 'downgrade' | 'cancel' | 'expired' | 'past_due'" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="feature_quantities" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="quantity" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="balances" type="object" />
<DynamicResponseField name="period_start" type="number" />
<DynamicResponseField name="period_end" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="redirect_type" type="'stripe_checkout' | 'autumn_checkout'" />

View File

@@ -0,0 +1,259 @@
---
title: "Billing Preview Update"
openapi: "openapi POST /v1/billing.preview_update"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
### Body Parameters
<DynamicParamField body="customer_id" type="string" required>
The ID of the customer to attach the plan to.
</DynamicParamField>
<DynamicParamField body="entity_id" type="string | null">
The ID of the entity to attach the plan to.
</DynamicParamField>
<DynamicParamField body="feature_quantities" type="object[] | null">
If this plan contains prepaid features, use this field to specify the quantity of each prepaid feature. This quantity includes the included amount and billing units defined when setting up the plan.
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required />
<DynamicParamField body="quantity" type="number" />
<DynamicParamField body="adjustable" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="version" type="number" />
<DynamicParamField body="free_trial" type="object | null">
<Expandable title="properties">
<DynamicParamField body="duration_length" type="number" required />
<DynamicParamField body="duration_type" type="'day' | 'month' | 'year'" />
<DynamicParamField body="card_required" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="customize" type="object">
<Expandable title="properties">
<DynamicParamField body="price" type="object | null">
<Expandable title="properties">
<DynamicParamField body="amount" type="number" required />
<DynamicParamField body="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" required />
<DynamicParamField body="interval_count" type="number" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="items" type="object[]">
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required />
<DynamicParamField body="included" type="number" />
<DynamicParamField body="unlimited" type="boolean" />
<DynamicParamField body="reset" type="object">
<Expandable title="properties">
<DynamicParamField body="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" required />
<DynamicParamField body="interval_count" type="number" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="price" type="object">
<Expandable title="properties">
<DynamicParamField body="amount" type="number" />
<DynamicParamField body="tiers" type="object[]">
<Expandable title="properties">
<DynamicParamField body="to" type="number" required />
<DynamicParamField body="amount" type="number" required />
</Expandable>
</DynamicParamField>
<DynamicParamField body="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" required />
<DynamicParamField body="interval_count" type="number" />
<DynamicParamField body="billing_units" type="number" />
<DynamicParamField body="billing_method" type="'prepaid' | 'usage_based'" required />
<DynamicParamField body="max_purchase" type="number" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="proration" type="object">
<Expandable title="properties">
<DynamicParamField body="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" required />
<DynamicParamField body="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" required />
</Expandable>
</DynamicParamField>
<DynamicParamField body="rollover" type="object">
<Expandable title="properties">
<DynamicParamField body="max" type="number" />
<DynamicParamField body="expiry_duration_type" type="'month' | 'forever'" required />
<DynamicParamField body="expiry_duration_length" type="number" />
</Expandable>
</DynamicParamField>
</Expandable>
</DynamicParamField>
</Expandable>
</DynamicParamField>
<DynamicParamField body="plan_id" type="string | null" />
<DynamicParamField body="invoice_mode" type="object">
<Expandable title="properties">
<DynamicParamField body="enabled" type="boolean" required />
<DynamicParamField body="enable_product_immediately" type="boolean" />
<DynamicParamField body="finalize_invoice" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="cancel_action" type="'cancel_immediately' | 'cancel_end_of_cycle' | 'uncancel'" />
<DynamicParamField body="billing_behavior" type="'prorate_immediately' | 'next_cycle_only'" />
### Response
<DynamicResponseField name="customer_id" type="string" />
<DynamicResponseField name="line_items" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="title" type="string" />
<DynamicResponseField name="description" type="string" />
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="discounts" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="amountOff" type="number" />
<DynamicResponseField name="percentOff" type="number" />
<DynamicResponseField name="stripeCouponId" type="string" />
<DynamicResponseField name="couponName" type="string" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="is_base" type="boolean" />
<DynamicResponseField name="total_quantity" type="number" />
<DynamicResponseField name="paid_quantity" type="number" />
<DynamicResponseField name="plan_id" type="string" />
<DynamicResponseField name="deferred_for_trial" type="boolean" />
<DynamicResponseField name="effective_period" type="object">
<Expandable title="properties">
<DynamicResponseField name="start" type="number" />
<DynamicResponseField name="end" type="number" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="total" type="number" />
<DynamicResponseField name="currency" type="string" />
<DynamicResponseField name="period_start" type="number" />
<DynamicResponseField name="period_end" type="number" />
<DynamicResponseField name="credit" type="object">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="description" type="string" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="next_cycle" type="object">
<Expandable title="properties">
<DynamicResponseField name="starts_at" type="number" />
<DynamicResponseField name="total" type="number" />
<DynamicResponseField name="line_items" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="title" type="string" />
<DynamicResponseField name="description" type="string" />
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="discounts" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="amountOff" type="number" />
<DynamicResponseField name="percentOff" type="number" />
<DynamicResponseField name="stripeCouponId" type="string" />
<DynamicResponseField name="couponName" type="string" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="is_base" type="boolean" />
<DynamicResponseField name="total_quantity" type="number" />
<DynamicResponseField name="paid_quantity" type="number" />
<DynamicResponseField name="plan_id" type="string" />
<DynamicResponseField name="deferred_for_trial" type="boolean" />
<DynamicResponseField name="effective_period" type="object">
<Expandable title="properties">
<DynamicResponseField name="start" type="number" />
<DynamicResponseField name="end" type="number" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>

View File

@@ -0,0 +1,71 @@
---
title: "Billing Setup Payment"
openapi: "openapi POST /v1/billing.setup_payment"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
### Body Parameters
<DynamicParamField body="customer_id" type="string" required>
The ID of the customer
</DynamicParamField>
<DynamicParamField body="success_url" type="string">
URL to redirect to after successful payment setup. Must start with either http:// or https://
</DynamicParamField>
<DynamicParamField body="customer_data" type="object">
Customer details to set when creating a customer
<Expandable title="properties">
<DynamicParamField body="name" type="string | null">
Customer's name
</DynamicParamField>
<DynamicParamField body="email" type="string | null">
Customer's email address
</DynamicParamField>
<DynamicParamField body="fingerprint" type="string | null">
Unique identifier (eg, serial number) to detect duplicate customers and prevent free trial abuse
</DynamicParamField>
<DynamicParamField body="metadata" type="object | null">
Additional metadata for the customer
</DynamicParamField>
<DynamicParamField body="stripe_id" type="string | null">
Stripe customer ID if you already have one
</DynamicParamField>
<DynamicParamField body="create_in_stripe" type="boolean">
Whether to create the customer in Stripe
</DynamicParamField>
<DynamicParamField body="auto_enable_plan_id" type="string">
The ID of the free plan to auto-enable for the customer
</DynamicParamField>
<DynamicParamField body="send_email_receipts" type="boolean">
Whether to send email receipts to this customer
</DynamicParamField>
</Expandable>
</DynamicParamField>
<DynamicParamField body="checkout_session_params" type="object">
Additional parameters for the checkout session
</DynamicParamField>
### Response
<DynamicResponseField name="customer_id" type="string">
The ID of the customer
</DynamicResponseField>
<DynamicResponseField name="url" type="string">
URL to the payment setup page
</DynamicResponseField>

View File

@@ -0,0 +1,175 @@
---
title: "Billing Update"
openapi: "openapi POST /v1/billing.update"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
### Body Parameters
<DynamicParamField body="customer_id" type="string" required>
The ID of the customer to attach the plan to.
</DynamicParamField>
<DynamicParamField body="entity_id" type="string | null">
The ID of the entity to attach the plan to.
</DynamicParamField>
<DynamicParamField body="feature_quantities" type="object[] | null">
If this plan contains prepaid features, use this field to specify the quantity of each prepaid feature. This quantity includes the included amount and billing units defined when setting up the plan.
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required />
<DynamicParamField body="quantity" type="number" />
<DynamicParamField body="adjustable" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="version" type="number" />
<DynamicParamField body="free_trial" type="object | null">
<Expandable title="properties">
<DynamicParamField body="duration_length" type="number" required />
<DynamicParamField body="duration_type" type="'day' | 'month' | 'year'" />
<DynamicParamField body="card_required" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="customize" type="object">
<Expandable title="properties">
<DynamicParamField body="price" type="object | null">
<Expandable title="properties">
<DynamicParamField body="amount" type="number" required />
<DynamicParamField body="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" required />
<DynamicParamField body="interval_count" type="number" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="items" type="object[]">
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required />
<DynamicParamField body="included" type="number" />
<DynamicParamField body="unlimited" type="boolean" />
<DynamicParamField body="reset" type="object">
<Expandable title="properties">
<DynamicParamField body="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" required />
<DynamicParamField body="interval_count" type="number" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="price" type="object">
<Expandable title="properties">
<DynamicParamField body="amount" type="number" />
<DynamicParamField body="tiers" type="object[]">
<Expandable title="properties">
<DynamicParamField body="to" type="number" required />
<DynamicParamField body="amount" type="number" required />
</Expandable>
</DynamicParamField>
<DynamicParamField body="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" required />
<DynamicParamField body="interval_count" type="number" />
<DynamicParamField body="billing_units" type="number" />
<DynamicParamField body="billing_method" type="'prepaid' | 'usage_based'" required />
<DynamicParamField body="max_purchase" type="number" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="proration" type="object">
<Expandable title="properties">
<DynamicParamField body="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" required />
<DynamicParamField body="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" required />
</Expandable>
</DynamicParamField>
<DynamicParamField body="rollover" type="object">
<Expandable title="properties">
<DynamicParamField body="max" type="number" />
<DynamicParamField body="expiry_duration_type" type="'month' | 'forever'" required />
<DynamicParamField body="expiry_duration_length" type="number" />
</Expandable>
</DynamicParamField>
</Expandable>
</DynamicParamField>
</Expandable>
</DynamicParamField>
<DynamicParamField body="plan_id" type="string | null" />
<DynamicParamField body="invoice_mode" type="object">
<Expandable title="properties">
<DynamicParamField body="enabled" type="boolean" required />
<DynamicParamField body="enable_product_immediately" type="boolean" />
<DynamicParamField body="finalize_invoice" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="cancel_action" type="'cancel_immediately' | 'cancel_end_of_cycle' | 'uncancel'" />
<DynamicParamField body="billing_behavior" type="'prorate_immediately' | 'next_cycle_only'" />
### Response
<DynamicResponseField name="customer_id" type="string" />
<DynamicResponseField name="entity_id" type="string" />
<DynamicResponseField name="invoice" type="object">
<Expandable title="properties">
<DynamicResponseField name="status" type="string | null" />
<DynamicResponseField name="stripe_id" type="string" />
<DynamicResponseField name="total" type="number" />
<DynamicResponseField name="currency" type="string" />
<DynamicResponseField name="hosted_invoice_url" type="string | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="payment_url" type="string | null" />
<DynamicResponseField name="required_action" type="object">
<Expandable title="properties">
<DynamicResponseField name="code" type="'3ds_required' | 'payment_method_required' | 'payment_failed'" />
<DynamicResponseField name="reason" type="string" />
</Expandable>
</DynamicResponseField>

View File

@@ -1,6 +1,6 @@
---
title: "Get or Create Customer"
openapi: "openapi POST /v1/customers.getOrCreate"
openapi: "openapi POST /v1/customers.get_or_create"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";

View File

@@ -1,6 +1,6 @@
---
title: "List Plans"
openapi: "openapi GET /v1/products"
openapi: "openapi GET /v1/plans.list"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";

View File

@@ -0,0 +1,210 @@
---
title: "List all plans"
openapi: "openapi POST /v1/plans.list"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
### Body Parameters
<DynamicParamField body="customer_id" type="string" />
<DynamicParamField body="entity_id" type="string" />
<DynamicParamField body="include_archived" type="boolean" />
### Response
<DynamicResponseField name="list" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="id" type="string" />
<DynamicResponseField name="name" type="string" />
<DynamicResponseField name="description" type="string | null" />
<DynamicResponseField name="group" type="string | null" />
<DynamicResponseField name="version" type="number" />
<DynamicResponseField name="add_on" type="boolean" />
<DynamicResponseField name="auto_enable" type="boolean" />
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="display" type="object">
<Expandable title="properties">
<DynamicResponseField name="primary_text" type="string" />
<DynamicResponseField name="secondary_text" type="string" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="items" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="feature" type="object">
<Expandable title="properties">
<DynamicResponseField name="id" type="string">
The ID of the feature, used to refer to it in other API calls like /track or /check.
</DynamicResponseField>
<DynamicResponseField name="name" type="string | null">
The name of the feature.
</DynamicResponseField>
<DynamicResponseField name="type" type="'static' | 'boolean' | 'single_use' | 'continuous_use' | 'credit_system'">
The type of the feature
</DynamicResponseField>
<DynamicResponseField name="display" type="object | null">
Singular and plural display names for the feature.
<Expandable title="properties">
<DynamicResponseField name="singular" type="string">
The singular display name for the feature.
</DynamicResponseField>
<DynamicResponseField name="plural" type="string">
The plural display name for the feature.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="credit_schema" type="object[] | null">
Credit cost schema for credit system features.
<Expandable title="properties">
<DynamicResponseField name="metered_feature_id" type="string">
The ID of the metered feature (should be a single_use feature).
</DynamicResponseField>
<DynamicResponseField name="credit_cost" type="number">
The credit cost of the metered feature.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="archived" type="boolean | null">
Whether or not the feature is archived.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="included" type="number" />
<DynamicResponseField name="unlimited" type="boolean" />
<DynamicResponseField name="reset" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="tiers" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="to" type="number" />
<DynamicResponseField name="amount" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="interval" type="'one_off' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="billing_units" type="number" />
<DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'" />
<DynamicResponseField name="max_purchase" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="display" type="object">
<Expandable title="properties">
<DynamicResponseField name="primary_text" type="string" />
<DynamicResponseField name="secondary_text" type="string" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rollover" type="object">
<Expandable title="properties">
<DynamicResponseField name="max" type="number | null" />
<DynamicResponseField name="expiry_duration_type" type="'month' | 'forever'" />
<DynamicResponseField name="expiry_duration_length" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="proration" type="object">
<Expandable title="properties">
<DynamicResponseField name="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" />
<DynamicResponseField name="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="free_trial" type="object">
<Expandable title="properties">
<DynamicResponseField name="duration_length" type="number" />
<DynamicResponseField name="duration_type" type="'day' | 'month' | 'year'" />
<DynamicResponseField name="card_required" type="boolean" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="created_at" type="number" />
<DynamicResponseField name="env" type="'sandbox' | 'live'" />
<DynamicResponseField name="archived" type="boolean" />
<DynamicResponseField name="base_variant_id" type="string | null" />
<DynamicResponseField name="customer_eligibility" type="object">
<Expandable title="properties">
<DynamicResponseField name="trial_available" type="boolean" />
<DynamicResponseField name="scenario" type="'scheduled' | 'active' | 'new' | 'renew' | 'upgrade' | 'downgrade' | 'cancel' | 'expired' | 'past_due'" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
"private": true,
"scripts": {
"pull": "bun scripts/pull.ts",
"dev": "cd mintlify && mint dev -p 3002",
"dev": "cd mintlify && mint dev -p 3003",
"build": "cd mintlify && mint build",
"start": "cd mintlify && mint dev"
},

View File

@@ -0,0 +1,5 @@
{
"workspaceId": "4afad568-ca97-46db-b7d4-632ebea401f1",
"defaultEnvironment": "",
"gitBranchToEnvironmentMapping": null
}

View File

@@ -0,0 +1,4 @@
import { toNextJsHandler } from "better-auth/next-js";
import { auth } from "@/lib/auth";
export const { GET, POST } = toNextJsHandler(auth);

View File

@@ -0,0 +1,27 @@
import { sql } from "kysely";
import { type NextRequest, NextResponse } from "next/server";
import { db } from "@/lib/db";
export async function DELETE(request: NextRequest) {
const { searchParams } = new URL(request.url);
const id = searchParams.get("id");
if (!id) {
return NextResponse.json({ error: "User ID required" }, { status: 400 });
}
try {
// Delete related records first (sessions, accounts), then user
await sql`DELETE FROM session WHERE "userId" = ${id}`.execute(db);
await sql`DELETE FROM account WHERE "userId" = ${id}`.execute(db);
await sql`DELETE FROM "user" WHERE id = ${id}`.execute(db);
return NextResponse.json({ success: true });
} catch (error) {
console.error("Failed to delete user:", error);
return NextResponse.json(
{ error: "Failed to delete user" },
{ status: 500 },
);
}
}

View File

@@ -0,0 +1,21 @@
import { type NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
export async function POST(request: NextRequest) {
try {
const body = await request.json().catch(() => ({}));
const result = await auth.api.getOrCreateCustomer({
headers: request.headers,
body,
});
return NextResponse.json(result);
} catch (error) {
console.error("Failed to get/create customer:", error);
return NextResponse.json(
{ error: error instanceof Error ? error.message : "Unknown error" },
{ status: 500 },
);
}
}

View File

@@ -1,52 +1,3 @@
import { autumnHandler } from "autumn-js/next";
import { logServerDebug, summarizeBody } from "@/lib/autumn/debug";
import { SDK_TEST_IDENTITY } from "@/lib/autumn/testIdentity";
import { handler } from "@/lib/autumn/autumnHandler";
const handler = autumnHandler({
secretKey: process.env.AUTUMN_SECRET_KEY,
baseURL: "http://localhost:8080",
identify: async (request: Request) => {
logServerDebug({
label: "identify",
payload: {
method: request.method,
url: request.url,
resolvedCustomerId: SDK_TEST_IDENTITY.customerId,
resolvedCustomerData: SDK_TEST_IDENTITY.customerData,
},
});
return SDK_TEST_IDENTITY;
},
});
const logRequest = async ({ request }: { request: Request }) => {
let body: unknown = null;
if (request.method !== "GET") {
try {
body = await request.clone().json();
} catch {
body = null;
}
}
logServerDebug({
label: "incoming-request",
payload: {
method: request.method,
url: request.url,
bodySummary: summarizeBody({ body }),
},
});
};
export async function GET(request: Request) {
await logRequest({ request });
return handler.GET(request);
}
export async function POST(request: Request) {
await logRequest({ request });
return handler.POST(request);
}
export const { GET, POST, DELETE } = handler;

View File

@@ -5,7 +5,12 @@
--foreground: #09090b;
--panel: #ffffff;
--muted: #71717a;
--muted-foreground: #71717a;
--border: #e4e4e7;
--input: #e4e4e7;
--ring: #a1a1aa;
--primary: #18181b;
--primary-foreground: #fafafa;
}
@media (prefers-color-scheme: dark) {
@@ -14,13 +19,24 @@
--foreground: #fafafa;
--panel: #09090b;
--muted: #a1a1aa;
--muted-foreground: #a1a1aa;
--border: #27272a;
--input: #27272a;
--ring: #52525b;
--primary: #fafafa;
--primary-foreground: #18181b;
}
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-muted-foreground: var(--muted-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}

View File

@@ -1,11 +1,5 @@
"use client";
import { AutumnProvider } from "autumn-js/react";
export const Providers = ({ children }: { children: React.ReactNode }) => {
return (
<AutumnProvider backendUrl="" pathPrefix="/api/autumn">
{children}
</AutumnProvider>
);
return <>{children}</>;
};

View File

@@ -0,0 +1,11 @@
"use client";
import { AutumnProvider } from "autumn-js/react";
export default function BetterAuthLayout({
children,
}: {
children: React.ReactNode;
}) {
return <AutumnProvider useBetterAuth>{children}</AutumnProvider>;
}

View File

@@ -0,0 +1,124 @@
"use client";
import { useState } from "react";
import { DebugCard } from "@/components/debug/DebugCard";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { authClient, useSession } from "@/lib/auth-client";
export function AuthControls({
onError,
onSignOut,
}: {
onError: (error: unknown) => void;
onSignOut: () => void;
}) {
const { data: session, isPending: sessionLoading } = useSession();
const [email, setEmail] = useState("test@example.com");
const [password, setPassword] = useState("password123");
const [name, setName] = useState("Test User");
const handleSignUp = async () => {
const result = await authClient.signUp.email({ email, password, name });
if (result.error) onError(result.error);
};
const handleSignIn = async () => {
const result = await authClient.signIn.email({ email, password });
if (result.error) onError(result.error);
};
const handleSignOut = async () => {
await authClient.signOut();
onSignOut();
};
const handleDeleteUser = async () => {
if (!session?.user?.id) return;
if (!confirm("Delete this user? This cannot be undone.")) return;
try {
const response = await fetch(
`/api/auth/delete-user?id=${session.user.id}`,
{ method: "DELETE" },
);
if (response.ok) {
await authClient.signOut();
onSignOut();
} else {
onError(await response.json());
}
} catch (err) {
onError(err);
}
};
return (
<DebugCard title="Auth Controls">
{sessionLoading ? (
<p className="text-sm text-zinc-500">Loading session...</p>
) : session ? (
<div className="space-y-3">
<p className="text-sm">
Signed in as{" "}
<span className="font-medium">{session.user.email}</span>
</p>
<div className="flex gap-2">
<Button variant="outline" size="sm" onClick={handleSignOut}>
Sign Out
</Button>
<Button
variant="ghost"
size="sm"
onClick={handleDeleteUser}
className="text-red-600 hover:text-red-700 hover:bg-red-50"
>
Delete User
</Button>
</div>
</div>
) : (
<div className="space-y-4">
<div className="grid gap-3 sm:grid-cols-3">
<div className="space-y-1.5">
<Label htmlFor="name">Name</Label>
<Input
id="name"
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
<div className="space-y-1.5">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="space-y-1.5">
<Label htmlFor="password">Password</Label>
<Input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
</div>
<div className="flex gap-2">
<Button size="sm" onClick={handleSignUp}>
Sign Up
</Button>
<Button variant="outline" size="sm" onClick={handleSignIn}>
Sign In
</Button>
</div>
</div>
)}
</DebugCard>
);
}

View File

@@ -0,0 +1,56 @@
"use client";
import { useState } from "react";
import { DebugCard } from "@/components/debug/DebugCard";
import { Button } from "@/components/ui/button";
export function BackendTest({
onResult,
onError,
}: {
onResult: (data: unknown) => void;
onError: (error: unknown) => void;
}) {
const [isLoading, setIsLoading] = useState(false);
const testBackendCustomer = async () => {
setIsLoading(true);
try {
const response = await fetch("/api/auth/test-customer", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ expand: ["invoices", "payment_method"] }),
credentials: "include",
});
const data = await response.json();
if (!response.ok) {
onError(data);
} else {
onResult(data);
}
} catch (err) {
onError(err);
} finally {
setIsLoading(false);
}
};
return (
<DebugCard
title="Backend: auth.api.getOrCreateCustomer"
actions={
<Button variant="outline" size="sm" onClick={testBackendCustomer}>
{isLoading ? "Loading..." : "Test"}
</Button>
}
>
<p className="text-sm text-zinc-500">
Calls{" "}
<code className="text-xs bg-zinc-100 px-1 py-0.5 rounded">
auth.api.getOrCreateCustomer
</code>{" "}
on the server
</p>
</DebugCard>
);
}

View File

@@ -0,0 +1,137 @@
"use client";
import { useState } from "react";
import { DebugCard } from "@/components/debug/DebugCard";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { authClient } from "@/lib/auth-client";
export function OrgControls({
onError,
}: {
onError: (error: unknown) => void;
}) {
const activeOrg = authClient.useActiveOrganization();
const { data: organizations } = authClient.useListOrganizations();
const [orgName, setOrgName] = useState("Test Org");
const [orgSlug, setOrgSlug] = useState("test-org");
const [selectedOrgId, setSelectedOrgId] = useState<string>("");
const handleCreateOrg = async () => {
const result = await authClient.organization.create({
name: orgName,
slug: orgSlug,
});
if (result.error) onError(result.error);
};
const handleSetActiveOrg = async () => {
if (!selectedOrgId) return;
await authClient.organization.setActive({ organizationId: selectedOrgId });
};
const handleClearActiveOrg = async () => {
await authClient.organization.setActive({ organizationId: null });
};
const handleDeleteOrg = async () => {
if (!selectedOrgId) return;
if (!confirm("Delete this organization? This cannot be undone.")) return;
const result = await authClient.organization.delete({
organizationId: selectedOrgId,
});
if (result.error) onError(result.error);
else setSelectedOrgId("");
};
return (
<DebugCard title="Organization Controls">
<div className="space-y-4">
{/* Create Org */}
<div className="grid gap-3 sm:grid-cols-2">
<div className="space-y-1.5">
<Label htmlFor="orgName">Org Name</Label>
<Input
id="orgName"
type="text"
value={orgName}
onChange={(e) => setOrgName(e.target.value)}
/>
</div>
<div className="space-y-1.5">
<Label htmlFor="orgSlug">Org Slug</Label>
<Input
id="orgSlug"
type="text"
value={orgSlug}
onChange={(e) => setOrgSlug(e.target.value)}
/>
</div>
</div>
<Button size="sm" onClick={handleCreateOrg}>
Create Org
</Button>
{/* Select & Manage Org */}
{organizations && organizations.length > 0 && (
<>
<div className="border-t border-zinc-200 dark:border-zinc-800 pt-4">
<div className="space-y-1.5">
<Label htmlFor="selectOrg">Select Organization</Label>
<select
id="selectOrg"
value={selectedOrgId}
onChange={(e) => setSelectedOrgId(e.target.value)}
className="h-7 w-full rounded border border-input bg-transparent px-2 py-0.5 text-sm outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-2"
>
<option value="">-- Select --</option>
{organizations.map((org) => (
<option key={org.id} value={org.id}>
{org.name} ({org.slug})
</option>
))}
</select>
</div>
</div>
<div className="flex gap-2 flex-wrap">
<Button
variant="outline"
size="sm"
onClick={handleSetActiveOrg}
disabled={!selectedOrgId}
>
Set Active
</Button>
<Button
variant="outline"
size="sm"
onClick={handleClearActiveOrg}
>
Clear Active
</Button>
<Button
variant="ghost"
size="sm"
onClick={handleDeleteOrg}
disabled={!selectedOrgId}
className="text-red-600 hover:text-red-700 hover:bg-red-50"
>
Delete Org
</Button>
</div>
</>
)}
{activeOrg.data && (
<p className="text-sm text-zinc-500">
Active org:{" "}
<span className="font-medium">{activeOrg.data.name}</span> (
{activeOrg.data.slug})
</p>
)}
</div>
</DebugCard>
);
}

View File

@@ -0,0 +1,3 @@
export { AuthControls } from "./AuthControls";
export { BackendTest } from "./BackendTest";
export { OrgControls } from "./OrgControls";

View File

@@ -1,13 +1,121 @@
export default function BetterAuthUseCustomerScenarioPage() {
"use client";
import { useCustomer } from "autumn-js/react";
import { useMemo, useState } from "react";
import { DataViewer } from "@/components/debug/DataViewer";
import { DebugCard } from "@/components/debug/DebugCard";
import { HookStatePanel } from "@/components/debug/HookStatePanel";
import { Button } from "@/components/ui/button";
import { authClient, useSession } from "@/lib/auth-client";
import { AuthControls, BackendTest, OrgControls } from "./components";
export default function BetterAuthUseCustomerPage() {
const { data: session } = useSession();
const activeOrg = authClient.useActiveOrganization();
// Shared error state
const [error, setError] = useState<unknown>(null);
// Backend test state
const [backendCustomer, setBackendCustomer] = useState<unknown>(null);
// useCustomer hook
const params = useMemo(
() => ({
errorOnNotFound: false,
expand: ["invoices", "payment_method"] as (
| "invoices"
| "payment_method"
)[],
}),
[],
);
const {
data: hookCustomer,
isLoading: hookLoading,
error: hookError,
refetch,
} = useCustomer(params);
const [lastUpdatedAt, setLastUpdatedAt] = useState<string | null>(null);
const onRefetch = async () => {
await refetch();
setLastUpdatedAt(new Date().toISOString());
};
const handleSignOut = () => {
setBackendCustomer(null);
setError(null);
};
return (
<div className="space-y-2">
<h1 className="text-lg font-semibold tracking-tight">
Better Auth / useCustomer
</h1>
<p className="text-sm text-zinc-500">
Planned next: route through autumn-js/better-auth plugin and inspect
end-to-end auth-coupled flow.
</p>
<div className="space-y-4">
{/* Auth & Org Controls Row */}
<div className="grid gap-4 lg:grid-cols-2">
<AuthControls onError={setError} onSignOut={handleSignOut} />
{session && <OrgControls onError={setError} />}
</div>
{/* Backend Test & Hook State Row */}
{session && (
<div className="grid gap-4 lg:grid-cols-2">
<BackendTest onResult={setBackendCustomer} onError={setError} />
<DebugCard
title="Hook: useCustomer"
actions={
<Button variant="outline" size="sm" onClick={onRefetch}>
Refetch
</Button>
}
>
<HookStatePanel
isLoading={hookLoading}
error={hookError}
lastUpdatedAt={lastUpdatedAt}
/>
</DebugCard>
</div>
)}
{/* Data Viewers */}
<div className="grid gap-4 lg:grid-cols-2">
<DataViewer
title="Backend Customer (auth.api)"
value={backendCustomer}
defaultExpandedDepth={2}
/>
<DataViewer
title="Hook Customer (useCustomer)"
value={hookCustomer}
defaultExpandedDepth={2}
/>
</div>
<div className="grid gap-4 lg:grid-cols-2">
<DataViewer title="Session" value={session} defaultExpandedDepth={2} />
<DataViewer
title="Active Organization"
value={activeOrg.data}
defaultExpandedDepth={2}
/>
</div>
{(error || hookError) && (
<DataViewer
title="Error"
value={
error ||
(hookError
? {
message: hookError.message,
code: hookError.code,
statusCode: hookError.statusCode,
}
: null)
}
defaultExpandedDepth={2}
/>
)}
</div>
);
}

View File

@@ -0,0 +1,15 @@
"use client";
import { AutumnProvider } from "autumn-js/react";
export default function CoreLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<AutumnProvider>
{children}
</AutumnProvider>
);
}

View File

@@ -1,11 +1,267 @@
"use client";
import type { ClientAttachParams } from "autumn-js/react";
import { useCustomer } from "autumn-js/react";
import { useId, useState } from "react";
import { DataViewer } from "@/components/debug/DataViewer";
import { DebugCard } from "@/components/debug/DebugCard";
import { HookStatePanel } from "@/components/debug/HookStatePanel";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
type ActionTab = "attach" | "check";
type LastActionState = {
name: string;
params: unknown;
result: unknown;
error: unknown;
executedAt: string;
} | null;
const toErrorPayload = ({ error }: { error: unknown }) => {
if (error instanceof Error) {
const typed = error as Error & {
code?: string;
statusCode?: number;
details?: unknown;
};
return {
message: typed.message,
code: typed.code ?? null,
statusCode: typed.statusCode ?? null,
details: typed.details ?? null,
name: typed.name,
};
}
return {
message: "Unknown error",
raw: error,
};
};
export default function UseAutumnScenarioPage() {
const {
data: customer,
isLoading,
error,
refetch,
attach,
check,
} = useCustomer({
errorOnNotFound: false,
});
const [lastUpdatedAt, setLastUpdatedAt] = useState<string | null>(null);
const [isRunning, setIsRunning] = useState(false);
const [lastAction, setLastAction] = useState<LastActionState>(null);
// Tab state
const [activeTab, setActiveTab] = useState<ActionTab>("attach");
// Input state
const [planId, setPlanId] = useState("");
const [featureId, setFeatureId] = useState("");
const [openInNewTab, setOpenInNewTab] = useState(false);
// Form element IDs
const planIdInputId = useId();
const featureIdInputId = useId();
const runAction = async ({
name,
params,
execute,
}: {
name: string;
params: unknown;
execute: () => Promise<unknown> | unknown;
}) => {
setIsRunning(true);
try {
const result = await Promise.resolve(execute());
setLastAction({
name,
params,
result,
error: null,
executedAt: new Date().toISOString(),
});
} catch (err) {
setLastAction({
name,
params,
result: null,
error: toErrorPayload({ error: err }),
executedAt: new Date().toISOString(),
});
} finally {
setIsRunning(false);
}
};
const onRefetch = async () => {
await refetch();
setLastUpdatedAt(new Date().toISOString());
};
const handleAttach = () => {
if (!planId) return;
const params: ClientAttachParams = {
planId,
openInNewTab,
newBillingSubscription: true,
};
runAction({
name: "attach",
params,
execute: () => attach(params),
});
};
const handleCheck = () => {
if (!featureId) return;
runAction({
name: "check",
params: { featureId },
execute: () => check({ featureId }),
});
};
return (
<div className="space-y-2">
<h1 className="text-lg font-semibold tracking-tight">Core / useAutumn</h1>
<p className="text-sm text-zinc-500">
Planned next: action-level testing for attach, checkout, cancel, track,
and billing portal calls.
</p>
<div className="space-y-4">
<DebugCard
title="Hook State"
actions={
<Button variant="outline" size="sm" onClick={onRefetch}>
Refetch
</Button>
}
>
<HookStatePanel
isLoading={isLoading}
error={error}
lastUpdatedAt={lastUpdatedAt}
/>
</DebugCard>
<DebugCard title="Actions">
{/* Tabs */}
<div className="flex gap-1 border-b border-zinc-200 mb-4">
<button
type="button"
onClick={() => setActiveTab("attach")}
className={`px-3 py-1.5 text-sm font-medium border-b-2 -mb-px transition-colors ${
activeTab === "attach"
? "border-zinc-900 text-zinc-900"
: "border-transparent text-zinc-500 hover:text-zinc-700"
}`}
>
Attach
</button>
<button
type="button"
onClick={() => setActiveTab("check")}
className={`px-3 py-1.5 text-sm font-medium border-b-2 -mb-px transition-colors ${
activeTab === "check"
? "border-zinc-900 text-zinc-900"
: "border-transparent text-zinc-500 hover:text-zinc-700"
}`}
>
Check
</button>
</div>
{/* Tab content */}
{activeTab === "attach" && (
<div className="space-y-3">
<div className="space-y-1.5">
<Label htmlFor={planIdInputId} className="text-xs text-zinc-500">
Plan ID
</Label>
<Input
id={planIdInputId}
placeholder="Enter plan ID"
value={planId}
onChange={(e) => setPlanId(e.target.value)}
className="h-8 text-sm"
/>
</div>
<label className="flex items-center gap-2 text-sm text-zinc-600">
<input
type="checkbox"
checked={openInNewTab}
onChange={(e) => setOpenInNewTab(e.target.checked)}
className="rounded border-zinc-300"
/>
Open in new tab
</label>
<Button
size="sm"
disabled={isRunning || !planId}
onClick={handleAttach}
>
{isRunning ? "Running..." : "Attach"}
</Button>
</div>
)}
{activeTab === "check" && (
<div className="space-y-3">
<div className="space-y-1.5">
<Label
htmlFor={featureIdInputId}
className="text-xs text-zinc-500"
>
Feature ID
</Label>
<Input
id={featureIdInputId}
placeholder="Enter feature ID"
value={featureId}
onChange={(e) => setFeatureId(e.target.value)}
className="h-8 text-sm"
/>
</div>
<Button
size="sm"
disabled={isRunning || !featureId}
onClick={handleCheck}
>
{isRunning ? "Running..." : "Check"}
</Button>
</div>
)}
</DebugCard>
<div className="grid gap-4 lg:grid-cols-2">
<DataViewer
title="Last Action Request"
value={
lastAction
? {
name: lastAction.name,
executedAt: lastAction.executedAt,
params: lastAction.params,
}
: null
}
defaultExpandedDepth={3}
/>
<DataViewer
title="Last Action Result"
value={lastAction?.result ?? null}
defaultExpandedDepth={3}
/>
</div>
<DataViewer
title="Last Action Error"
value={lastAction?.error ?? null}
defaultExpandedDepth={3}
/>
</div>
);
}

View File

@@ -1,11 +1,11 @@
"use client";
import { useCustomer } from "autumn-js/react";
import { useMemo, useState } from "react";
import { DataViewer } from "@/components/debug/DataViewer";
import { DebugCard } from "@/components/debug/DebugCard";
import { HookStatePanel } from "@/components/debug/HookStatePanel";
import { Button } from "@/components/ui/button";
import { useCustomer } from "autumn-js/react";
export default function UseCustomerScenarioPage() {
type UseCustomerParams = Parameters<typeof useCustomer>[0];
@@ -18,7 +18,15 @@ export default function UseCustomerScenarioPage() {
[],
);
const { customer, isLoading, error, refetch } = useCustomer(params);
const {
data: customer,
isLoading,
error,
refetch,
attach,
check,
} = useCustomer(params);
const [lastUpdatedAt, setLastUpdatedAt] = useState<string | null>(null);
const onRefetch = async () => {
@@ -28,19 +36,8 @@ export default function UseCustomerScenarioPage() {
return (
<div className="space-y-4">
<div>
<h1 className="text-lg font-semibold tracking-tight">
Core / useCustomer
</h1>
<p className="mt-1 text-sm text-zinc-500">
This page validates the default provider + autumnHandler path and
surfaces request state for debugging.
</p>
</div>
<DebugCard
title="Hook State"
description="Loading/error lifecycle for useCustomer"
actions={
<Button variant="outline" size="sm" onClick={onRefetch}>
Refetch
@@ -54,40 +51,28 @@ export default function UseCustomerScenarioPage() {
/>
</DebugCard>
<div className="grid gap-4 lg:grid-cols-2">
<DebugCard
title="Hook Params"
description="Exact params passed to useCustomer()"
>
<DataViewer
title="useCustomer params"
value={params}
defaultExpandedDepth={3}
/>
</DebugCard>
<DebugCard
title="Customer Payload"
description="Latest customer object returned by autumn-js/react"
>
<div className="grid gap-4 md:grid-cols-2">
<DataViewer title="params" value={params} defaultExpandedDepth={3} />
<DataViewer
title="customer"
value={customer}
defaultExpandedDepth={2}
/>
</DebugCard>
</div>
<DebugCard title="Error Payload" description="Error object (if any)">
<DataViewer
title="error"
value={
error
? { name: error.name, message: error.message, stack: error.stack }
? {
message: error.message,
code: error.code,
statusCode: error.statusCode,
}
: null
}
defaultExpandedDepth={2}
/>
</DebugCard>
</div>
);
}

View File

@@ -0,0 +1,53 @@
"use client";
import { useListPlans } from "autumn-js/react";
import { useState } from "react";
import { DataViewer } from "@/components/debug/DataViewer";
import { DebugCard } from "@/components/debug/DebugCard";
import { HookStatePanel } from "@/components/debug/HookStatePanel";
import { Button } from "@/components/ui/button";
export default function UseListPlansScenarioPage() {
const { data: plans, isLoading, error, refetch } = useListPlans();
const [lastUpdatedAt, setLastUpdatedAt] = useState<string | null>(null);
const onRefetch = async () => {
await refetch();
setLastUpdatedAt(new Date().toISOString());
};
return (
<div className="space-y-4">
<DebugCard
title="Hook State"
actions={
<Button variant="outline" size="sm" onClick={onRefetch}>
Refetch
</Button>
}
>
<HookStatePanel
isLoading={isLoading}
error={error}
lastUpdatedAt={lastUpdatedAt}
/>
</DebugCard>
<DataViewer title="plans" value={plans} defaultExpandedDepth={2} />
<DataViewer
title="error"
value={
error
? {
message: error.message,
code: error.code,
statusCode: error.statusCode,
}
: null
}
defaultExpandedDepth={2}
/>
</div>
);
}

View File

@@ -1,92 +0,0 @@
"use client";
import { usePricingTable } from "autumn-js/react";
import { useMemo, useState } from "react";
import { DataViewer } from "@/components/debug/DataViewer";
import { DebugCard } from "@/components/debug/DebugCard";
import { HookStatePanel } from "@/components/debug/HookStatePanel";
import { Button } from "@/components/ui/button";
export default function UsePricingTableScenarioPage() {
type UsePricingTableParams = Parameters<typeof usePricingTable>[0];
const params = useMemo(
(): NonNullable<UsePricingTableParams> => ({
productDetails: undefined,
}),
[],
);
const { products, isLoading, error, refetch } = usePricingTable(params);
const [lastUpdatedAt, setLastUpdatedAt] = useState<string | null>(null);
const onRefetch = async () => {
await refetch();
setLastUpdatedAt(new Date().toISOString());
};
return (
<div className="space-y-4">
<div>
<h1 className="text-lg font-semibold tracking-tight">
Core / usePricingTable
</h1>
<p className="mt-1 text-sm text-zinc-500">
This page validates the usePricingTable hook which fetches and merges
product data for pricing table display.
</p>
</div>
<DebugCard
title="Hook State"
description="Loading/error lifecycle for usePricingTable"
actions={
<Button variant="outline" size="sm" onClick={onRefetch}>
Refetch
</Button>
}
>
<HookStatePanel
isLoading={isLoading}
error={error}
lastUpdatedAt={lastUpdatedAt}
/>
</DebugCard>
<div className="grid gap-4 lg:grid-cols-2">
<DebugCard
title="Hook Params"
description="Exact params passed to usePricingTable()"
>
<DataViewer
title="usePricingTable params"
value={params}
defaultExpandedDepth={3}
/>
</DebugCard>
<DebugCard
title="Products Payload"
description="Merged products array returned by autumn-js/react"
>
<DataViewer
title="products"
value={products}
defaultExpandedDepth={2}
/>
</DebugCard>
</div>
<DebugCard title="Error Payload" description="Error object (if any)">
<DataViewer
title="error"
value={
error
? { name: error.name, message: error.message, stack: error.stack }
: null
}
defaultExpandedDepth={2}
/>
</DebugCard>
</div>
);
}

View File

@@ -0,0 +1,29 @@
create table "user" ("id" text not null primary key, "name" text not null, "email" text not null unique, "emailVerified" boolean not null, "image" text, "createdAt" timestamptz default CURRENT_TIMESTAMP not null, "updatedAt" timestamptz default CURRENT_TIMESTAMP not null);
create table "session" ("id" text not null primary key, "expiresAt" timestamptz not null, "token" text not null unique, "createdAt" timestamptz default CURRENT_TIMESTAMP not null, "updatedAt" timestamptz not null, "ipAddress" text, "userAgent" text, "userId" text not null references "user" ("id") on delete cascade, "activeOrganizationId" text);
create table "account" ("id" text not null primary key, "accountId" text not null, "providerId" text not null, "userId" text not null references "user" ("id") on delete cascade, "accessToken" text, "refreshToken" text, "idToken" text, "accessTokenExpiresAt" timestamptz, "refreshTokenExpiresAt" timestamptz, "scope" text, "password" text, "createdAt" timestamptz default CURRENT_TIMESTAMP not null, "updatedAt" timestamptz not null);
create table "verification" ("id" text not null primary key, "identifier" text not null, "value" text not null, "expiresAt" timestamptz not null, "createdAt" timestamptz default CURRENT_TIMESTAMP not null, "updatedAt" timestamptz default CURRENT_TIMESTAMP not null);
create table "organization" ("id" text not null primary key, "name" text not null, "slug" text not null unique, "logo" text, "createdAt" timestamptz not null, "metadata" text);
create table "member" ("id" text not null primary key, "organizationId" text not null references "organization" ("id") on delete cascade, "userId" text not null references "user" ("id") on delete cascade, "role" text not null, "createdAt" timestamptz not null);
create table "invitation" ("id" text not null primary key, "organizationId" text not null references "organization" ("id") on delete cascade, "email" text not null, "role" text, "status" text not null, "expiresAt" timestamptz not null, "createdAt" timestamptz default CURRENT_TIMESTAMP not null, "inviterId" text not null references "user" ("id") on delete cascade);
create index "session_userId_idx" on "session" ("userId");
create index "account_userId_idx" on "account" ("userId");
create index "verification_identifier_idx" on "verification" ("identifier");
create unique index "organization_slug_uidx" on "organization" ("slug");
create index "member_organizationId_idx" on "member" ("organizationId");
create index "member_userId_idx" on "member" ("userId");
create index "invitation_organizationId_idx" on "invitation" ("organizationId");
create index "invitation_email_idx" on "invitation" ("email");

View File

@@ -4,7 +4,6 @@ import Link from "next/link";
import { usePathname } from "next/navigation";
import { useMemo, useState } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { findScenarioByHref, scenarioSections } from "@/lib/scenarios";
import { cn } from "@/lib/utils";
@@ -38,7 +37,7 @@ export const AppSidebarLayout = ({
<p className="mb-2 px-2 text-[11px] font-medium uppercase tracking-wide text-zinc-500">
{section.title}
</p>
<div className="space-y-1">
<div className="space-y-0.5">
{section.items.map((item) => {
const activeItem = pathname === item.href;
return (
@@ -47,26 +46,19 @@ export const AppSidebarLayout = ({
href={item.href}
onClick={() => setOpenMobile(false)}
className={cn(
"block rounded-md border px-2 py-2 transition-colors",
"flex items-center justify-between gap-2 rounded-md px-2 py-1.5 text-sm",
activeItem
? "border-zinc-900 bg-zinc-900 text-white dark:border-zinc-100 dark:bg-zinc-100 dark:text-black"
: "border-zinc-200 bg-white hover:bg-zinc-100 dark:border-zinc-800 dark:bg-zinc-950 dark:hover:bg-zinc-900",
? "bg-zinc-900 text-white dark:bg-zinc-100 dark:text-black"
: "text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-900",
)}
>
<div className="flex items-center justify-between gap-2">
<p className="text-sm font-medium">{item.title}</p>
<Badge variant={item.status}>{item.status}</Badge>
</div>
<p
className={cn(
"mt-1 text-xs",
activeItem
? "text-zinc-300 dark:text-zinc-700"
: "text-zinc-500",
)}
<span className="font-medium">{item.title}</span>
<Badge
variant={item.status}
className="text-[10px] px-1.5 py-0"
>
{item.description}
</p>
{item.status}
</Badge>
</Link>
);
})}
@@ -80,7 +72,7 @@ export const AppSidebarLayout = ({
return (
<div className="min-h-screen bg-background text-foreground">
<div className="flex h-screen">
<aside className="hidden w-72 border-r border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-950 md:block">
<aside className="hidden w-56 border-r border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-950 md:block">
{sidebarContent}
</aside>
@@ -88,14 +80,14 @@ export const AppSidebarLayout = ({
type="button"
aria-label="Close menu"
className={cn(
"fixed inset-0 z-40 bg-black/40 backdrop-blur-sm transition-opacity md:hidden",
"fixed inset-0 z-40 bg-black/40 backdrop-blur-sm md:hidden",
openMobile ? "opacity-100" : "pointer-events-none opacity-0",
)}
onClick={() => setOpenMobile(false)}
/>
<aside
className={cn(
"fixed inset-y-0 left-0 z-50 w-72 border-r border-zinc-200 bg-white transition-transform dark:border-zinc-800 dark:bg-zinc-950 md:hidden",
"fixed inset-y-0 left-0 z-50 w-56 border-r border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-950 md:hidden",
openMobile ? "translate-x-0" : "-translate-x-full",
)}
>
@@ -107,7 +99,7 @@ export const AppSidebarLayout = ({
<div className="flex items-center gap-2">
<Link
href="/"
className="inline-flex h-8 items-center justify-center rounded-md border border-zinc-300 bg-white px-3 text-xs font-medium text-zinc-900 transition-colors hover:bg-zinc-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-400 dark:border-zinc-700 dark:bg-black dark:text-zinc-100 dark:hover:bg-zinc-900"
className="inline-flex h-8 items-center justify-center rounded-md border border-zinc-300 bg-white px-3 text-xs font-medium text-zinc-900 hover:bg-zinc-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-400 dark:border-zinc-700 dark:bg-black dark:text-zinc-100 dark:hover:bg-zinc-900"
>
Menu
</Link>

View File

@@ -1,7 +1,6 @@
"use client";
import { useMemo } from "react";
import { Button } from "@/components/ui/button";
import { useMemo, useState } from "react";
import { cn, toPrettyJson } from "@/lib/utils";
type DataViewerProps = {
@@ -11,6 +10,84 @@ type DataViewerProps = {
maxHeight?: number;
};
const highlightJson = (json: string | undefined): React.ReactNode[] => {
if (!json) return [];
const parts: React.ReactNode[] = [];
let i = 0;
const regex =
/("(?:\\.|[^"\\])*")\s*:|("(?:\\.|[^"\\])*")|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|(\btrue\b|\bfalse\b)|(\bnull\b)/g;
let lastIndex = 0;
let match: RegExpExecArray | null = regex.exec(json);
while (match !== null) {
if (match.index > lastIndex) {
parts.push(
<span key={i++} className="text-zinc-500">
{json.slice(lastIndex, match.index)}
</span>,
);
}
if (match[1]) {
// Key
parts.push(
<span key={i++} className="text-zinc-600 dark:text-zinc-400">
{match[1]}
</span>,
);
parts.push(
<span key={i++} className="text-zinc-500">
:
</span>,
);
} else if (match[2]) {
// String value
parts.push(
<span key={i++} className="text-emerald-600 dark:text-emerald-400">
{match[2]}
</span>,
);
} else if (match[3]) {
// Number
parts.push(
<span key={i++} className="text-blue-600 dark:text-blue-400">
{match[3]}
</span>,
);
} else if (match[4]) {
// Boolean
parts.push(
<span key={i++} className="text-amber-600 dark:text-amber-400">
{match[4]}
</span>,
);
} else if (match[5]) {
// Null
parts.push(
<span key={i++} className="text-zinc-500">
{match[5]}
</span>,
);
}
lastIndex = regex.lastIndex;
match = regex.exec(json);
}
if (lastIndex < json.length) {
parts.push(
<span key={i++} className="text-zinc-500">
{json.slice(lastIndex)}
</span>,
);
}
return parts;
};
const renderPrimitive = ({ value }: { value: unknown }) => {
if (value === null) return <span className="text-zinc-500">null</span>;
if (value === undefined)
@@ -85,26 +162,62 @@ export const DataViewer = ({
defaultExpandedDepth = 2,
maxHeight = 420,
}: DataViewerProps) => {
const [viewMode, setViewMode] = useState<"tree" | "raw">("raw");
const [copied, setCopied] = useState(false);
const prettyJson = useMemo(() => toPrettyJson({ value }), [value]);
const onCopy = async () => {
await navigator.clipboard.writeText(prettyJson);
setCopied(true);
setTimeout(() => setCopied(false), 1500);
};
return (
<div className="rounded-md border border-zinc-200 dark:border-zinc-800">
<div className="flex items-center justify-between border-b border-zinc-200 bg-zinc-50 px-3 py-2 dark:border-zinc-800 dark:bg-zinc-900">
<div className="flex items-center justify-between border-b border-zinc-200 bg-zinc-50 px-3 py-1.5 dark:border-zinc-800 dark:bg-zinc-900">
<p className="text-xs font-semibold uppercase tracking-wide text-zinc-600 dark:text-zinc-300">
{title}
</p>
<Button
variant="outline"
size="sm"
onClick={onCopy}
className="h-7 px-2 text-[11px]"
<div className="flex items-center gap-0.5">
<div className="flex rounded border border-zinc-200 dark:border-zinc-700">
<button
type="button"
onClick={() => setViewMode("tree")}
className={cn(
"px-1.5 py-0.5 text-[10px] font-medium",
viewMode === "tree"
? "bg-zinc-900 text-white dark:bg-zinc-100 dark:text-black"
: "text-zinc-500 hover:text-zinc-900 dark:hover:text-zinc-100",
)}
>
Copy JSON
</Button>
Tree
</button>
<button
type="button"
onClick={() => setViewMode("raw")}
className={cn(
"px-1.5 py-0.5 text-[10px] font-medium",
viewMode === "raw"
? "bg-zinc-900 text-white dark:bg-zinc-100 dark:text-black"
: "text-zinc-500 hover:text-zinc-900 dark:hover:text-zinc-100",
)}
>
Raw
</button>
</div>
<button
type="button"
onClick={onCopy}
className={cn(
"rounded border px-1.5 py-0.5 text-[10px] font-medium",
copied
? "border-emerald-300 bg-emerald-50 text-emerald-700 dark:border-emerald-700 dark:bg-emerald-950 dark:text-emerald-400"
: "border-zinc-200 text-zinc-500 hover:text-zinc-900 dark:border-zinc-700 dark:hover:text-zinc-100",
)}
>
{copied ? "Copied" : "Copy"}
</button>
</div>
</div>
<div
className={cn(
@@ -112,12 +225,16 @@ export const DataViewer = ({
)}
style={{ maxHeight }}
>
{viewMode === "tree" ? (
<JsonNode
name="root"
value={value}
depth={0}
defaultExpandedDepth={defaultExpandedDepth}
/>
) : (
<pre className="whitespace-pre-wrap">{highlightJson(prettyJson)}</pre>
)}
</div>
</div>
);

View File

@@ -1,12 +1,14 @@
import type { ButtonHTMLAttributes } from "react";
import { type ButtonHTMLAttributes, type MouseEvent, useState } from "react";
import { cn } from "@/lib/utils";
type ButtonVariant = "default" | "outline" | "ghost";
type ButtonSize = "sm" | "md";
type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
type ButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, "onClick"> & {
variant?: ButtonVariant;
size?: ButtonSize;
loading?: boolean;
onClick?: (e: MouseEvent<HTMLButtonElement>) => void | Promise<void>;
};
const variantClasses: Record<ButtonVariant, string> = {
@@ -19,25 +21,73 @@ const variantClasses: Record<ButtonVariant, string> = {
};
const sizeClasses: Record<ButtonSize, string> = {
sm: "h-8 px-3 text-xs",
md: "h-9 px-4 text-sm",
sm: "h-7 px-2.5 text-xs",
md: "h-8 px-3 text-sm",
};
const Spinner = ({ className }: { className?: string }) => (
<svg
className={cn("animate-spin", className)}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
);
export const Button = ({
className,
variant = "default",
size = "md",
loading: controlledLoading,
disabled,
onClick,
children,
...props
}: ButtonProps) => {
const [internalLoading, setInternalLoading] = useState(false);
const isLoading = controlledLoading ?? internalLoading;
const handleClick = async (e: MouseEvent<HTMLButtonElement>) => {
if (!onClick || isLoading) return;
const result = onClick(e);
if (result instanceof Promise) {
setInternalLoading(true);
try {
await result;
} finally {
setInternalLoading(false);
}
}
};
return (
<button
className={cn(
"inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-400 disabled:pointer-events-none disabled:opacity-50",
"inline-flex items-center justify-center gap-1.5 rounded-md font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-400 disabled:pointer-events-none disabled:opacity-50",
variantClasses[variant],
sizeClasses[size],
className,
)}
disabled={disabled || isLoading}
onClick={handleClick}
{...props}
/>
>
{isLoading && <Spinner className="h-3.5 w-3.5" />}
{children}
</button>
);
};

View File

@@ -0,0 +1,21 @@
import type * as React from "react";
import { cn } from "@/lib/utils";
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
return (
<input
type={type}
data-slot="input"
className={cn(
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-7 w-full min-w-0 rounded border bg-transparent px-2 py-0.5 text-sm shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-5 file:border-0 file:bg-transparent file:text-xs file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[2px]",
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
className,
)}
{...props}
/>
);
}
export { Input };

View File

@@ -0,0 +1,24 @@
"use client"
import * as React from "react"
import { Label as LabelPrimitive } from "radix-ui"
import { cn } from "@/lib/utils"
function Label({
className,
...props
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
return (
<LabelPrimitive.Root
data-slot="label"
className={cn(
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
className
)}
{...props}
/>
)
}
export { Label }

View File

@@ -0,0 +1,10 @@
"use client";
import { organizationClient } from "better-auth/client/plugins";
import { createAuthClient } from "better-auth/react";
export const authClient = createAuthClient({
plugins: [organizationClient()],
});
export const { signIn, signUp, signOut, useSession } = authClient;

24
apps/sdk-test/lib/auth.ts Normal file
View File

@@ -0,0 +1,24 @@
import { autumn } from "autumn-js/better-auth";
import { betterAuth } from "better-auth";
import { organization } from "better-auth/plugins";
import { db } from "./db";
export const auth = betterAuth({
database: {
db,
type: "postgres",
},
emailAndPassword: {
enabled: true,
},
plugins: [
organization(),
autumn({
secretKey: process.env.AUTUMN_SECRET_KEY,
baseURL: process.env.NEXT_PUBLIC_URL,
customerScope: "user_and_organization",
}),
],
});
export type Session = typeof auth.$Infer.Session;

View File

@@ -0,0 +1,11 @@
import { autumnHandler } from "autumn-js/backend/next";
import { SDK_TEST_IDENTITY } from "./testIdentity";
/** Set to true to simulate an unauthenticated user */
const SIMULATE_UNAUTHENTICATED = false;
export const handler = autumnHandler({
secretKey: process.env.AUTUMN_SECRET_KEY,
baseURL: "http://localhost:8080",
identify: async () => (SIMULATE_UNAUTHENTICATED ? null : SDK_TEST_IDENTITY),
});

10
apps/sdk-test/lib/db.ts Normal file
View File

@@ -0,0 +1,10 @@
import { Kysely, PostgresDialect } from "kysely";
import { Pool } from "pg";
const pool = new Pool({
connectionString: process.env.PACKAGES_DB_URL,
});
export const db = new Kysely({
dialect: new PostgresDialect({ pool }),
});

View File

@@ -26,12 +26,19 @@ export const scenarioSections: Array<ScenarioSection> = [
description: "Inspect customer fetch state and payloads.",
status: "ready",
},
{
id: "use-list-plans",
title: "useListPlans",
href: "/scenarios/core/use-list-plans",
description: "Inspect plans list and payloads.",
status: "ready",
},
{
id: "use-autumn",
title: "useAutumn",
href: "/scenarios/core/use-autumn",
description: "Test generic SDK action helpers.",
status: "planned",
description: "Test attach/check action helpers and inspect payloads.",
status: "ready",
},
{
id: "use-entity",
@@ -40,13 +47,6 @@ export const scenarioSections: Array<ScenarioSection> = [
description: "Inspect entity-level behavior.",
status: "planned",
},
{
id: "use-pricing-table",
title: "usePricingTable",
href: "/scenarios/core/use-pricing-table",
description: "Inspect pricing table product data.",
status: "ready",
},
],
},
{
@@ -58,7 +58,7 @@ export const scenarioSections: Array<ScenarioSection> = [
title: "useCustomer",
href: "/scenarios/better-auth/use-customer",
description: "Validate better-auth plugin routing.",
status: "planned",
status: "ready",
},
],
},

View File

@@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"dev": "infisical run --env=dev -- next dev -p 3002",
"build": "next build",
"start": "next start",
"lint": "biome check",
@@ -12,7 +12,11 @@
},
"dependencies": {
"autumn-js": "workspace:*",
"better-auth": "^1.4.12",
"kysely": "^0.28.11",
"next": "16.1.6",
"pg": "^8.18.0",
"radix-ui": "^1.4.3",
"react": "19.2.3",
"react-dom": "19.2.3"
},
@@ -20,6 +24,7 @@
"@biomejs/biome": "2.2.0",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/pg": "^8.16.0",
"@types/react": "^19",
"@types/react-dom": "^19",
"tailwindcss": "^4",

View File

@@ -9,6 +9,15 @@ const autumn = new Autumn({
secretKey: process.env.AUTUMN_SECRET_KEY,
});
const customer = await autumn.customers.list();
const customer = await autumn.customers.getOrCreate({
customerId: "123",
});
console.log("Customer:", customer);
const attachResult = await autumn.billing.attach({
customerId: customer.id ?? "",
planId: "pro_plan",
});
console.log("Attach result:", attachResult);

View File

@@ -37,11 +37,18 @@
"@sdk/*": ["../../packages/autumn-js/src/sdk/*"],
"@utils/*": ["../../packages/autumn-js/src/utils/*"],
"autumn-js": ["../../packages/autumn-js/src/sdk/index.ts"],
"autumn-js/react": [
"../../packages/autumn-js/src/libraries/react/index.ts"
],
"autumn-js/react": ["../../packages/autumn-js/src/react/index.ts"],
"autumn-js/next": [
"../../packages/autumn-js/src/libraries/backend/next.ts"
],
"autumn-js/backend/next": [
"../../packages/autumn-js/src/backend/adapters/next.ts"
],
"autumn-js/better-auth": [
"../../packages/autumn-js/src/better-auth/index.ts"
],
"autumn-js/better-auth/client": [
"../../packages/autumn-js/src/better-auth/client.ts"
]
}
},

254
bun.lock
View File

@@ -24,6 +24,7 @@
"dotenv": "^16.6.1",
"husky": "^9.1.7",
"inquirer": "^12.10.0",
"ts-to-zod": "^5.1.0",
},
},
"apps/checkout": {
@@ -79,7 +80,11 @@
"version": "0.1.0",
"dependencies": {
"autumn-js": "workspace:*",
"better-auth": "^1.4.12",
"kysely": "^0.28.11",
"next": "16.1.6",
"pg": "^8.18.0",
"radix-ui": "^1.4.3",
"react": "19.2.3",
"react-dom": "19.2.3",
},
@@ -87,6 +92,7 @@
"@biomejs/biome": "2.2.0",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/pg": "^8.16.0",
"@types/react": "^19",
"@types/react-dom": "^19",
"tailwindcss": "^4",
@@ -106,6 +112,7 @@
"devDependencies": {
"@remix-run/node": "^2.16.6",
"@supabase/ssr": "^0.6.1",
"@tanstack/react-query": "catalog:",
"@tanstack/react-start": "^1.120.5",
"@types/express": "^5.0.1",
"@types/node": "^22.15.32",
@@ -125,13 +132,17 @@
"typescript": "^5.8.3",
},
"peerDependencies": {
"@tanstack/react-query": "^5.0.0",
"better-auth": "^1.3.17",
"better-call": "^1.0.12",
"convex": "^1.25.4",
"react": "^18.0.0 || ^19.0.0",
},
"optionalPeers": [
"@tanstack/react-query",
"better-auth",
"better-call",
"react",
],
},
"packages/openapi": {
@@ -155,7 +166,7 @@
},
"packages/sdk": {
"name": "@useautumn/sdk",
"version": "0.8.11",
"version": "0.8.25",
"dependencies": {
"zod": "^3.25.65 || ^4.0.0",
},
@@ -364,7 +375,7 @@
"@squircle/tailwindcss": "^1.0.6",
"@tailwindcss/vite": "^4.0.13",
"@tanstack/react-form": "^1.23.8",
"@tanstack/react-query": "^5.85.6",
"@tanstack/react-query": "catalog:",
"@tanstack/react-table": "^8.21.3",
"@tanstack/react-virtual": "^3.13.18",
"ag-charts-community": "^12.0.2",
@@ -449,6 +460,7 @@
"@orpc/contract": "^1.0.0",
"@orpc/openapi-client": "^1.0.0",
"@sentry/bun": "10.38.0",
"@tanstack/react-query": "5.85.6",
"drizzle-kit": "^0.31.1",
"drizzle-orm": "0.43.1",
"stripe": "19.3.0-beta.1",
@@ -976,6 +988,32 @@
"@leichtgewicht/ip-codec": ["@leichtgewicht/ip-codec@2.0.5", "", {}, "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw=="],
"@libsql/client": ["@libsql/client@0.17.0", "", { "dependencies": { "@libsql/core": "^0.17.0", "@libsql/hrana-client": "^0.9.0", "js-base64": "^3.7.5", "libsql": "^0.5.22", "promise-limit": "^2.7.0" } }, "sha512-TLjSU9Otdpq0SpKHl1tD1Nc9MKhrsZbCFGot3EbCxRa8m1E5R1mMwoOjKMMM31IyF7fr+hPNHLpYfwbMKNusmg=="],
"@libsql/core": ["@libsql/core@0.17.0", "", { "dependencies": { "js-base64": "^3.7.5" } }, "sha512-hnZRnJHiS+nrhHKLGYPoJbc78FE903MSDrFJTbftxo+e52X+E0Y0fHOCVYsKWcg6XgB7BbJYUrz/xEkVTSaipw=="],
"@libsql/darwin-arm64": ["@libsql/darwin-arm64@0.5.22", "", { "os": "darwin", "cpu": "arm64" }, "sha512-4B8ZlX3nIDPndfct7GNe0nI3Yw6ibocEicWdC4fvQbSs/jdq/RC2oCsoJxJ4NzXkvktX70C1J4FcmmoBy069UA=="],
"@libsql/darwin-x64": ["@libsql/darwin-x64@0.5.22", "", { "os": "darwin", "cpu": "x64" }, "sha512-ny2HYWt6lFSIdNFzUFIJ04uiW6finXfMNJ7wypkAD8Pqdm6nAByO+Fdqu8t7sD0sqJGeUCiOg480icjyQ2/8VA=="],
"@libsql/hrana-client": ["@libsql/hrana-client@0.9.0", "", { "dependencies": { "@libsql/isomorphic-ws": "^0.1.5", "cross-fetch": "^4.0.0", "js-base64": "^3.7.5", "node-fetch": "^3.3.2" } }, "sha512-pxQ1986AuWfPX4oXzBvLwBnfgKDE5OMhAdR/5cZmRaB4Ygz5MecQybvwZupnRz341r2CtFmbk/BhSu7k2Lm+Jw=="],
"@libsql/isomorphic-ws": ["@libsql/isomorphic-ws@0.1.5", "", { "dependencies": { "@types/ws": "^8.5.4", "ws": "^8.13.0" } }, "sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg=="],
"@libsql/linux-arm-gnueabihf": ["@libsql/linux-arm-gnueabihf@0.5.22", "", { "os": "linux", "cpu": "arm" }, "sha512-3Uo3SoDPJe/zBnyZKosziRGtszXaEtv57raWrZIahtQDsjxBVjuzYQinCm9LRCJCUT5t2r5Z5nLDPJi2CwZVoA=="],
"@libsql/linux-arm-musleabihf": ["@libsql/linux-arm-musleabihf@0.5.22", "", { "os": "linux", "cpu": "arm" }, "sha512-LCsXh07jvSojTNJptT9CowOzwITznD+YFGGW+1XxUr7fS+7/ydUrpDfsMX7UqTqjm7xG17eq86VkWJgHJfvpNg=="],
"@libsql/linux-arm64-gnu": ["@libsql/linux-arm64-gnu@0.5.22", "", { "os": "linux", "cpu": "arm64" }, "sha512-KSdnOMy88c9mpOFKUEzPskSaF3VLflfSUCBwas/pn1/sV3pEhtMF6H8VUCd2rsedwoukeeCSEONqX7LLnQwRMA=="],
"@libsql/linux-arm64-musl": ["@libsql/linux-arm64-musl@0.5.22", "", { "os": "linux", "cpu": "arm64" }, "sha512-mCHSMAsDTLK5YH//lcV3eFEgiR23Ym0U9oEvgZA0667gqRZg/2px+7LshDvErEKv2XZ8ixzw3p1IrBzLQHGSsw=="],
"@libsql/linux-x64-gnu": ["@libsql/linux-x64-gnu@0.5.22", "", { "os": "linux", "cpu": "x64" }, "sha512-kNBHaIkSg78Y4BqAdgjcR2mBilZXs4HYkAmi58J+4GRwDQZh5fIUWbnQvB9f95DkWUIGVeenqLRFY2pcTmlsew=="],
"@libsql/linux-x64-musl": ["@libsql/linux-x64-musl@0.5.22", "", { "os": "linux", "cpu": "x64" }, "sha512-UZ4Xdxm4pu3pQXjvfJiyCzZop/9j/eA2JjmhMaAhe3EVLH2g11Fy4fwyUp9sT1QJYR1kpc2JLuybPM0kuXv/Tg=="],
"@libsql/win32-x64-msvc": ["@libsql/win32-x64-msvc@0.5.22", "", { "os": "win32", "cpu": "x64" }, "sha512-Fj0j8RnBpo43tVZUVoNK6BV/9AtDUM5S7DF3LB4qTYg1LMSZqi3yeCneUTLJD6XomQJlZzbI4mst89yspVSAnA=="],
"@mdx-js/mdx": ["@mdx-js/mdx@3.1.1", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "acorn": "^8.0.0", "collapse-white-space": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "markdown-extensions": "^2.0.0", "recma-build-jsx": "^1.0.0", "recma-jsx": "^1.0.0", "recma-stringify": "^1.0.0", "rehype-recma": "^1.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "source-map": "^0.7.0", "unified": "^11.0.0", "unist-util-position-from-estree": "^2.0.0", "unist-util-stringify-position": "^4.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ=="],
"@mdx-js/react": ["@mdx-js/react@3.1.1", "", { "dependencies": { "@types/mdx": "^2.0.0" }, "peerDependencies": { "@types/react": ">=16", "react": ">=16" } }, "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw=="],
@@ -1020,6 +1058,8 @@
"@mswjs/interceptors": ["@mswjs/interceptors@0.41.3", "", { "dependencies": { "@open-draft/deferred-promise": "^2.2.0", "@open-draft/logger": "^0.3.0", "@open-draft/until": "^2.0.0", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "strict-event-emitter": "^0.5.1" } }, "sha512-cXu86tF4VQVfwz8W1SPbhoRyHJkti6mjH/XJIxp40jhO4j2k1m4KYrEykxqWPkFF3vrK4rgQppBh//AwyGSXPA=="],
"@neon-rs/load": ["@neon-rs/load@0.0.4", "", {}, "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw=="],
"@next/env": ["@next/env@15.5.12", "", {}, "sha512-pUvdJN1on574wQHjaBfNGDt9Mz5utDSZFsIIQkMzPgNS8ZvT4H2mwOrOIClwsQOb6EGx5M76/CZr6G8i6pSpLg=="],
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.5.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RnRjBtH8S8eXCpUNkQ+543DUc7ys8y15VxmFU9HRqlo9BG3CcBUiwNtF8SNoi2xvGCVJq1vl2yYq+3oISBS0Zg=="],
@@ -1050,6 +1090,8 @@
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
"@oclif/core": ["@oclif/core@4.8.0", "", { "dependencies": { "ansi-escapes": "^4.3.2", "ansis": "^3.17.0", "clean-stack": "^3.0.1", "cli-spinners": "^2.9.2", "debug": "^4.4.3", "ejs": "^3.1.10", "get-package-type": "^0.1.0", "indent-string": "^4.0.0", "is-wsl": "^2.2.0", "lilconfig": "^3.1.3", "minimatch": "^9.0.5", "semver": "^7.7.3", "string-width": "^4.2.3", "supports-color": "^8", "tinyglobby": "^0.2.14", "widest-line": "^3.1.0", "wordwrap": "^1.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-jteNUQKgJHLHFbbz806aGZqf+RJJ7t4gwF4MYa8fCwCxQ8/klJNWc0MvaJiBebk7Mc+J39mdlsB4XraaCKznFw=="],
"@oozcitak/dom": ["@oozcitak/dom@2.0.2", "", { "dependencies": { "@oozcitak/infra": "^2.0.2", "@oozcitak/url": "^3.0.0", "@oozcitak/util": "^10.0.0" } }, "sha512-GjpKhkSYC3Mj4+lfwEyI1dqnsKTgwGy48ytZEhm4A/xnH/8z9M3ZVXKr/YGQi3uCLs1AEBS+x5T2JPiueEDW8w=="],
"@oozcitak/infra": ["@oozcitak/infra@2.0.2", "", { "dependencies": { "@oozcitak/util": "^10.0.0" } }, "sha512-2g+E7hoE2dgCz/APPOEK5s3rMhJvNxSMBrP+U+j1OWsIbtSpWxxlUjq1lU8RIsFJNYv7NMlnVsCuHcUzJW+8vA=="],
@@ -1308,10 +1350,18 @@
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
"@radix-ui/react-accessible-icon": ["@radix-ui/react-accessible-icon@1.1.7", "", { "dependencies": { "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A=="],
"@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collapsible": "1.1.12", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA=="],
"@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw=="],
"@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="],
"@radix-ui/react-aspect-ratio": ["@radix-ui/react-aspect-ratio@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g=="],
"@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.1.10", "", { "dependencies": { "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog=="],
"@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw=="],
"@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA=="],
@@ -1322,6 +1372,8 @@
"@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="],
"@radix-ui/react-context-menu": ["@radix-ui/react-context-menu@2.2.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww=="],
"@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="],
"@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="],
@@ -1334,6 +1386,8 @@
"@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="],
"@radix-ui/react-form": ["@radix-ui/react-form@0.1.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-label": "2.1.7", "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ=="],
"@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg=="],
"@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="],
@@ -1342,6 +1396,14 @@
"@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg=="],
"@radix-ui/react-menubar": ["@radix-ui/react-menubar@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA=="],
"@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w=="],
"@radix-ui/react-one-time-password-field": ["@radix-ui/react-one-time-password-field@0.1.8", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg=="],
"@radix-ui/react-password-toggle-field": ["@radix-ui/react-password-toggle-field@0.1.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-is-hydrated": "0.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/UuCrDBWravcaMix4TdT+qlNdVwOM1Nck9kWx/vafXsdfj1ChfhOdfi3cy9SGBpWgTXwYCuboT/oYpJy3clqfw=="],
"@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA=="],
"@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.8", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw=="],
@@ -1352,6 +1414,8 @@
"@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
"@radix-ui/react-progress": ["@radix-ui/react-progress@1.1.7", "", { "dependencies": { "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg=="],
"@radix-ui/react-radio-group": ["@radix-ui/react-radio-group@1.3.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ=="],
"@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA=="],
@@ -1362,12 +1426,22 @@
"@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g=="],
"@radix-ui/react-slider": ["@radix-ui/react-slider@1.3.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw=="],
"@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="],
"@radix-ui/react-switch": ["@radix-ui/react-switch@1.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ=="],
"@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="],
"@radix-ui/react-toast": ["@radix-ui/react-toast@1.2.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g=="],
"@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ=="],
"@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q=="],
"@radix-ui/react-toolbar": ["@radix-ui/react-toolbar@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-separator": "1.1.7", "@radix-ui/react-toggle-group": "1.1.11" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg=="],
"@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg=="],
"@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="],
@@ -1378,6 +1452,8 @@
"@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="],
"@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.0", "", { "dependencies": { "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA=="],
"@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="],
"@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ=="],
@@ -1766,11 +1842,11 @@
"@tanstack/pacer-lite": ["@tanstack/pacer-lite@0.1.1", "", {}, "sha512-y/xtNPNt/YeyoVxE/JCx+T7yjEzpezmbb+toK8DDD1P4m7Kzs5YR956+7OKexG3f8aXgC3rLZl7b1V+yNUSy5w=="],
"@tanstack/query-core": ["@tanstack/query-core@5.90.20", "", {}, "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg=="],
"@tanstack/query-core": ["@tanstack/query-core@5.85.6", "", {}, "sha512-hCj0TktzdCv2bCepIdfwqVwUVWb+GSHm1Jnn8w+40lfhQ3m7lCO7ADRUJy+2unxQ/nzjh2ipC6ye69NDW3l73g=="],
"@tanstack/react-form": ["@tanstack/react-form@1.28.3", "", { "dependencies": { "@tanstack/form-core": "1.28.3", "@tanstack/react-store": "^0.8.1" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-84yd0swZRcyC3Q46dYBH6bHf1tlIY1flchbdG3VwArg/wLVW5RdBenIrJhleHjk2OxXuF+9HoKQbHglJyWIXQA=="],
"@tanstack/react-query": ["@tanstack/react-query@5.90.21", "", { "dependencies": { "@tanstack/query-core": "5.90.20" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg=="],
"@tanstack/react-query": ["@tanstack/react-query@5.85.6", "", { "dependencies": { "@tanstack/query-core": "5.85.6" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-VUAag4ERjh+qlmg0wNivQIVCZUrYndqYu3/wPCVZd4r0E+1IqotbeyGTc+ICroL/PqbpSaGZg02zSWYfcvxbdA=="],
"@tanstack/react-router": ["@tanstack/react-router@1.160.0", "", { "dependencies": { "@tanstack/history": "1.154.14", "@tanstack/react-store": "^0.8.0", "@tanstack/router-core": "1.160.0", "isbot": "^5.1.22", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-leT/nymh9rKFVivy4b/F8/PZiMrLpotNiyemNg0/KjdZNzo5oVEdFnsXVFnBI1lL4WXRbiq7RK8+fI0SKsT6ww=="],
@@ -2132,7 +2208,7 @@
"ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
"ansis": ["ansis@4.2.0", "", {}, "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig=="],
"ansis": ["ansis@3.17.0", "", {}, "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg=="],
"any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="],
@@ -2168,6 +2244,8 @@
"astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="],
"async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="],
"async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="],
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
@@ -2332,7 +2410,7 @@
"class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="],
"clean-stack": ["clean-stack@4.2.0", "", { "dependencies": { "escape-string-regexp": "5.0.0" } }, "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg=="],
"clean-stack": ["clean-stack@3.0.1", "", { "dependencies": { "escape-string-regexp": "4.0.0" } }, "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg=="],
"cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="],
@@ -2428,6 +2506,8 @@
"cross-env": ["cross-env@7.0.3", "", { "dependencies": { "cross-spawn": "^7.0.1" }, "bin": { "cross-env": "src/bin/cross-env.js", "cross-env-shell": "src/bin/cross-env-shell.js" } }, "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw=="],
"cross-fetch": ["cross-fetch@4.1.0", "", { "dependencies": { "node-fetch": "^2.7.0" } }, "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw=="],
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
"css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
@@ -2644,6 +2724,8 @@
"ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
"ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="],
"electron-to-chromium": ["electron-to-chromium@1.5.286", "", {}, "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A=="],
"elysia": ["elysia@1.4.25", "", { "dependencies": { "cookie": "^1.1.1", "exact-mirror": "^0.2.7", "fast-decode-uri-component": "^1.0.1", "memoirist": "^0.4.0" }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "@types/bun": ">= 1.2.0", "file-type": ">= 20.0.0", "openapi-types": ">= 12.0.0", "typescript": ">= 5.0.0" }, "optionalPeers": ["@types/bun", "typescript"] }, "sha512-liKjavH99Gpzrv9cDil6uYWmPuqESfPFV1FIaFSd3iNqo3y7e29sN43VxFIK8tWWnyi6eDAmi2SZk8hNAMQMyg=="],
@@ -2824,6 +2906,8 @@
"file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="],
"filelist": ["filelist@1.0.4", "", { "dependencies": { "minimatch": "^5.0.1" } }, "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q=="],
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
"filter-obj": ["filter-obj@5.1.0", "", {}, "sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng=="],
@@ -2910,6 +2994,8 @@
"get-own-enumerable-keys": ["get-own-enumerable-keys@1.0.0", "", {}, "sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA=="],
"get-package-type": ["get-package-type@0.1.0", "", {}, "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q=="],
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
"get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="],
@@ -3200,7 +3286,7 @@
"is-weakset": ["is-weakset@2.0.4", "", { "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ=="],
"is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="],
"is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="],
"isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
@@ -3210,12 +3296,16 @@
"jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
"jake": ["jake@10.9.4", "", { "dependencies": { "async": "^3.2.6", "filelist": "^1.0.4", "picocolors": "^1.1.1" }, "bin": { "jake": "bin/cli.js" } }, "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA=="],
"jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
"jose": ["jose@6.1.3", "", {}, "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ=="],
"joycon": ["joycon@3.1.1", "", {}, "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw=="],
"js-base64": ["js-base64@3.7.8", "", {}, "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow=="],
"js-tiktoken": ["js-tiktoken@1.0.21", "", { "dependencies": { "base64-js": "^1.5.1" } }, "sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g=="],
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
@@ -3290,6 +3380,8 @@
"libphonenumber-js": ["libphonenumber-js@1.12.36", "", {}, "sha512-woWhKMAVx1fzzUnMCyOzglgSgf6/AFHLASdOBcchYCyvWSGWt12imw3iu2hdI5d4dGZRsNWAmWiz37sDKUPaRQ=="],
"libsql": ["libsql@0.5.22", "", { "dependencies": { "@neon-rs/load": "^0.0.4", "detect-libc": "2.0.2" }, "optionalDependencies": { "@libsql/darwin-arm64": "0.5.22", "@libsql/darwin-x64": "0.5.22", "@libsql/linux-arm-gnueabihf": "0.5.22", "@libsql/linux-arm-musleabihf": "0.5.22", "@libsql/linux-arm64-gnu": "0.5.22", "@libsql/linux-arm64-musl": "0.5.22", "@libsql/linux-x64-gnu": "0.5.22", "@libsql/linux-x64-musl": "0.5.22", "@libsql/win32-x64-msvc": "0.5.22" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "arm", "x64", "arm64", ] }, "sha512-NscWthMQt7fpU8lqd7LXMvT9pi+KhhmTHAJWUB/Lj6MWa0MKFv0F2V4C6WKKpjCVZl0VwcDz4nOI3CyaT1DDiA=="],
"light-my-request": ["light-my-request@6.6.0", "", { "dependencies": { "cookie": "^1.0.1", "process-warning": "^4.0.0", "set-cookie-parser": "^2.6.0" } }, "sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A=="],
"lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="],
@@ -3320,6 +3412,8 @@
"lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
"listr2": ["listr2@9.0.5", "", { "dependencies": { "cli-truncate": "^5.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" } }, "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g=="],
"load-tsconfig": ["load-tsconfig@0.2.5", "", {}, "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg=="],
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
@@ -3340,6 +3434,8 @@
"log-symbols": ["log-symbols@4.1.0", "", { "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg=="],
"log-update": ["log-update@6.1.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "cli-cursor": "^5.0.0", "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w=="],
"long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
"longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="],
@@ -3832,6 +3928,8 @@
"prom-client": ["prom-client@15.1.3", "", { "dependencies": { "@opentelemetry/api": "^1.4.0", "tdigest": "^0.1.1" } }, "sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g=="],
"promise-limit": ["promise-limit@2.7.0", "", {}, "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw=="],
"prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
@@ -3874,6 +3972,8 @@
"radash": ["radash@12.1.1", "", {}, "sha512-h36JMxKRqrAxVD8201FrCpyeNuUY9Y5zZwujr20fFO77tpUtGa6EZzfKw/3WaiBX95fq7+MpsuMLNdSnORAwSA=="],
"radix-ui": ["radix-ui@1.4.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-accessible-icon": "1.1.7", "@radix-ui/react-accordion": "1.2.12", "@radix-ui/react-alert-dialog": "1.1.15", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-aspect-ratio": "1.1.7", "@radix-ui/react-avatar": "1.1.10", "@radix-ui/react-checkbox": "1.3.3", "@radix-ui/react-collapsible": "1.1.12", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-context-menu": "2.2.16", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-dropdown-menu": "2.1.16", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-form": "0.1.8", "@radix-ui/react-hover-card": "1.1.15", "@radix-ui/react-label": "2.1.7", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-menubar": "1.1.16", "@radix-ui/react-navigation-menu": "1.2.14", "@radix-ui/react-one-time-password-field": "0.1.8", "@radix-ui/react-password-toggle-field": "0.1.3", "@radix-ui/react-popover": "1.1.15", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-progress": "1.1.7", "@radix-ui/react-radio-group": "1.3.8", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-scroll-area": "1.2.10", "@radix-ui/react-select": "2.2.6", "@radix-ui/react-separator": "1.1.7", "@radix-ui/react-slider": "1.3.6", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-switch": "1.2.6", "@radix-ui/react-tabs": "1.1.13", "@radix-ui/react-toast": "1.2.15", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-toggle-group": "1.1.11", "@radix-ui/react-toolbar": "1.1.11", "@radix-ui/react-tooltip": "1.2.8", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-escape-keydown": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA=="],
"randombytes": ["randombytes@2.1.0", "", { "dependencies": { "safe-buffer": "^5.1.0" } }, "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="],
"range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
@@ -4144,7 +4244,7 @@
"sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
"slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"slash": ["slash@5.1.0", "", {}, "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg=="],
"slice-ansi": ["slice-ansi@7.1.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w=="],
@@ -4282,8 +4382,50 @@
"terminal-size": ["terminal-size@4.0.1", "", {}, "sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ=="],
"text-camel-case": ["text-camel-case@1.2.10", "", { "dependencies": { "text-pascal-case": "1.2.10" } }, "sha512-KNrWeZzQT+gh73V1LnmgTkjK7V+tMRjLCc6VrGwkqbiRdnGVIWBUgIvVnvnaVCxIvZ/2Ke8DCmgPirlQcCqD3Q=="],
"text-capital-case": ["text-capital-case@1.2.10", "", { "dependencies": { "text-no-case": "1.2.10", "text-upper-case-first": "1.2.10" } }, "sha512-yvViUJKSSQcRO58je224bhPHg/Hij9MEY43zuKShtFzrPwW/fOAarUJ5UkTMSB81AOO1m8q+JiFdxMF4etKZbA=="],
"text-case": ["text-case@1.2.10", "", { "dependencies": { "text-camel-case": "1.2.10", "text-capital-case": "1.2.10", "text-constant-case": "1.2.10", "text-dot-case": "1.2.10", "text-header-case": "1.2.10", "text-is-lower-case": "1.2.10", "text-is-upper-case": "1.2.10", "text-kebab-case": "1.2.10", "text-lower-case": "1.2.10", "text-lower-case-first": "1.2.10", "text-no-case": "1.2.10", "text-param-case": "1.2.10", "text-pascal-case": "1.2.10", "text-path-case": "1.2.10", "text-sentence-case": "1.2.10", "text-snake-case": "1.2.10", "text-swap-case": "1.2.10", "text-title-case": "1.2.10", "text-upper-case": "1.2.10", "text-upper-case-first": "1.2.10" } }, "sha512-5bY3Ks/u7OJ5YO69iyXrG5Xf2wUZeyko7U78nPUnYoSeuNeAfA5uAix5hTspfkl6smm3yCBObrex+kFvzeIcJg=="],
"text-constant-case": ["text-constant-case@1.2.10", "", { "dependencies": { "text-no-case": "1.2.10", "text-upper-case": "1.2.10" } }, "sha512-/OfU798O2wrwKN9kQf71WhJeAlklGnbby0Tupp+Ez9NXymW+6oF9LWDRTkN+OreTmHucdvp4WQd6O5Rah5zj8A=="],
"text-decoder": ["text-decoder@1.2.7", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ=="],
"text-dot-case": ["text-dot-case@1.2.10", "", { "dependencies": { "text-no-case": "1.2.10" } }, "sha512-vf4xguy5y6e39RlDZeWZFMDf2mNkR23VTSVb9e68dUSpfJscG9/1YWWpW3n8TinzQxBZlsn5sT5olL33MvvQXw=="],
"text-header-case": ["text-header-case@1.2.10", "", { "dependencies": { "text-capital-case": "1.2.10" } }, "sha512-sVb1NY9bwxtu+Z7CVyWbr+I0AkWtF0kEHL/Zz5V2u/WdkjK5tKBwl5nXf0NGy9da4ZUYTBb+TmQpOIqihzvFMQ=="],
"text-is-lower-case": ["text-is-lower-case@1.2.10", "", {}, "sha512-dMTeTgrdWWfYf3fKxvjMkDPuXWv96cWbd1Uym6Zjv9H855S1uHxjkFsGbTYJ2tEK0NvAylRySTQlI6axlcMc4w=="],
"text-is-upper-case": ["text-is-upper-case@1.2.10", "", {}, "sha512-PGD/cXoXECGAY1HVZxDdmpJUW2ZUAKQ6DTamDfCHC9fc/z4epOz0pB/ThBnjJA3fz+d2ApkMjAfZDjuZFcodzg=="],
"text-kebab-case": ["text-kebab-case@1.2.10", "", { "dependencies": { "text-no-case": "1.2.10" } }, "sha512-3XZJAApx5JQpUO7eXo7GQ2TyRcGw3OVbqxz6QJb2h+N8PbLLbz3zJVeXdGrhTkoUIbkSZ6PmHx6LRDaHXTdMcA=="],
"text-lower-case": ["text-lower-case@1.2.10", "", {}, "sha512-c9j5pIAN3ObAp1+4R7970e1bgtahTRF/5ZQdX2aJBuBngYTYZZIck0NwFXUKk5BnYpLGsre5KFHvpqvf4IYKgg=="],
"text-lower-case-first": ["text-lower-case-first@1.2.10", "", {}, "sha512-Oro84jZPDLD9alfdZWmtFHYTvCaaSz2o4thPtjMsK4GAkTyVg9juYXWj0y0YFyjLYGH69muWsBe4/MR5S7iolw=="],
"text-no-case": ["text-no-case@1.2.10", "", { "dependencies": { "text-lower-case": "1.2.10" } }, "sha512-4/m79pzQrywrwEG5lCULY1lQvFY+EKjhH9xSMT6caPK5plqzm9Y7rXyv+UXPd3s9qH6QODZnvsAYWW3M0JgxRA=="],
"text-param-case": ["text-param-case@1.2.10", "", { "dependencies": { "text-dot-case": "1.2.10" } }, "sha512-hkavcLsRRzZcGryPAshct1AwIOMj/FexYjMaLpGZCYYBn1lcZEeyMzJZPSckzkOYpq35LYSQr3xZto9XU5OAsw=="],
"text-pascal-case": ["text-pascal-case@1.2.10", "", { "dependencies": { "text-no-case": "1.2.10" } }, "sha512-/kynZD8vTYOmm/RECjIDaz3qYEUZc/N/bnC79XuAFxwXjdNVjj/jGovKJLRzqsYK/39N22XpGcVmGg7yIrbk6w=="],
"text-path-case": ["text-path-case@1.2.10", "", { "dependencies": { "text-dot-case": "1.2.10" } }, "sha512-vbKdRCaVEeOaW6sm24QP9NbH7TS9S4ZQ3u19H8eylDox7m2HtFwYIBjAPv+v3z4I/+VjrMy9LB54lNP1uEqRHw=="],
"text-sentence-case": ["text-sentence-case@1.2.10", "", { "dependencies": { "text-no-case": "1.2.10", "text-upper-case-first": "1.2.10" } }, "sha512-NO4MRlbfxFhl9QgQLuCL4xHmvE7PUWHVPWsZxQ5nzRtDjXOUllWvtsvl8CP5tBEvBmzg0kwfflxfhRtr5vBQGg=="],
"text-snake-case": ["text-snake-case@1.2.10", "", { "dependencies": { "text-dot-case": "1.2.10" } }, "sha512-6ttMZ+B9jkHKun908HYr4xSvEtlbfJJ4MvpQ06JEKRGhwjMI0x8t2Wywp+MEzN6142O6E/zKhra18KyBL6cvXA=="],
"text-swap-case": ["text-swap-case@1.2.10", "", {}, "sha512-vO3jwInIk0N77oEFakYZ2Hn/llTmRwf2c3RvkX/LfvmLWVp+3QcIc6bwUEtbqGQ5Xh2okjFhYrfkHZstVc3N4Q=="],
"text-title-case": ["text-title-case@1.2.10", "", { "dependencies": { "text-no-case": "1.2.10", "text-upper-case-first": "1.2.10" } }, "sha512-bqA+WWexUMWu9A3fdNar+3GXXW+c5xOvMyuK5hOx/w0AlqhyQptyCrMFjGB8Fd9dxbryBNmJ+5rWtC1OBDxlaA=="],
"text-upper-case": ["text-upper-case@1.2.10", "", {}, "sha512-L1AtZ8R+jtSMTq0Ffma9R4Rzbrc3iuYW89BmWFH41AwnDfRmEBlBOllm1ZivRLQ/6pEu2p+3XKBHx9fsMl2CWg=="],
"text-upper-case-first": ["text-upper-case-first@1.2.10", "", {}, "sha512-VXs7j7BbpKwvolDh5fwpYRmMrUHGkxbY8E90fhBzKUoKfadvWmPT/jFieoZ4UPLzr208pXvQEFbb2zO9Qzs9Fg=="],
"thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="],
"thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="],
@@ -4346,6 +4488,8 @@
"ts-node": ["ts-node@10.9.2", "", { "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", "@tsconfig/node16": "^1.0.2", "acorn": "^8.4.1", "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "peerDependencies": { "@swc/core": ">=1.2.50", "@swc/wasm": ">=1.2.50", "@types/node": "*", "typescript": ">=2.7" }, "optionalPeers": ["@swc/core", "@swc/wasm"], "bin": { "ts-node": "dist/bin.js", "ts-script": "dist/bin-script-deprecated.js", "ts-node-cwd": "dist/bin-cwd.js", "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js" } }, "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ=="],
"ts-to-zod": ["ts-to-zod@5.1.0", "", { "dependencies": { "@clack/prompts": "1.0.0-alpha.4", "@oclif/core": "^4.5.4", "@typescript/vfs": "^1.5.0", "chokidar": "^4.0.3", "listr2": "^9.0.4", "slash": "^5.1.0", "text-case": "^1.2.4", "tslib": "^2.3.1", "tsutils": "^3.21.0", "typescript": "^5.2.2", "zod": "^4.1.5" }, "bin": { "ts-to-zod": "bin/run" } }, "sha512-giqqlvRHunlJqG9tBL/KAO3wWIVZGF//mZiWLKm/fdQnKnz4EN2mtiK5cugN9slytBkdMEXQIaLvMzIScbhhFw=="],
"tsc-alias": ["tsc-alias@1.8.16", "", { "dependencies": { "chokidar": "^3.5.3", "commander": "^9.0.0", "get-tsconfig": "^4.10.0", "globby": "^11.0.4", "mylas": "^2.1.9", "normalize-path": "^3.0.0", "plimit-lit": "^1.2.6" }, "bin": { "tsc-alias": "dist/bin/index.js" } }, "sha512-QjCyu55NFyRSBAl6+MTFwplpFcnm2Pq01rR/uxfqJoLMm6X3O14KEGtaSDZpJYaE1bJBGDjD0eSuiIWPe2T58g=="],
"tsconfck": ["tsconfck@3.1.6", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "tsconfck": "bin/tsconfck.js" } }, "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w=="],
@@ -4358,6 +4502,8 @@
"tsup": ["tsup@8.5.1", "", { "dependencies": { "bundle-require": "^5.1.0", "cac": "^6.7.14", "chokidar": "^4.0.3", "consola": "^3.4.0", "debug": "^4.4.0", "esbuild": "^0.27.0", "fix-dts-default-cjs-exports": "^1.0.0", "joycon": "^3.1.1", "picocolors": "^1.1.1", "postcss-load-config": "^6.0.1", "resolve-from": "^5.0.0", "rollup": "^4.34.8", "source-map": "^0.7.6", "sucrase": "^3.35.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.11", "tree-kill": "^1.2.2" }, "peerDependencies": { "@microsoft/api-extractor": "^7.36.0", "@swc/core": "^1", "postcss": "^8.4.12", "typescript": ">=4.5.0" }, "optionalPeers": ["@microsoft/api-extractor", "@swc/core", "postcss", "typescript"], "bin": { "tsup": "dist/cli-default.js", "tsup-node": "dist/cli-node.js" } }, "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing=="],
"tsutils": ["tsutils@3.21.0", "", { "dependencies": { "tslib": "^1.8.1" }, "peerDependencies": { "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA=="],
"tsx": ["tsx@4.21.0", "", { "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="],
"tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
@@ -4550,6 +4696,8 @@
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
"wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="],
"workerpool": ["workerpool@9.3.4", "", {}, "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg=="],
"wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="],
@@ -4608,6 +4756,8 @@
"@antfu/install-pkg/tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="],
"@antfu/ni/ansis": ["ansis@4.2.0", "", {}, "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig=="],
"@antfu/ni/tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="],
"@anthropic-ai/sdk/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
@@ -5026,6 +5176,8 @@
"@langchain/langgraph-sdk/uuid": ["uuid@13.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w=="],
"@libsql/hrana-client/node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="],
"@mintlify/cli/@inquirer/prompts": ["@inquirer/prompts@7.9.0", "", { "dependencies": { "@inquirer/checkbox": "^4.3.0", "@inquirer/confirm": "^5.1.19", "@inquirer/editor": "^4.2.21", "@inquirer/expand": "^4.0.21", "@inquirer/input": "^4.2.5", "@inquirer/number": "^3.0.21", "@inquirer/password": "^4.0.21", "@inquirer/rawlist": "^4.1.9", "@inquirer/search": "^3.2.0", "@inquirer/select": "^4.4.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-X7/+dG9SLpSzRkwgG5/xiIzW0oMrV3C0HOa7YHG1WnrLK+vCQHfte4k/T80059YBdei29RBC3s+pSMvPJDU9/A=="],
"@mintlify/cli/chalk": ["chalk@5.2.0", "", {}, "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA=="],
@@ -5142,6 +5294,18 @@
"@noble/curves/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
"@oclif/core/ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="],
"@oclif/core/indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="],
"@oclif/core/lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
"@oclif/core/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"@oclif/core/widest-line": ["widest-line@3.1.0", "", { "dependencies": { "string-width": "^4.0.0" } }, "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg=="],
"@oclif/core/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
"@opentelemetry/auto-instrumentations-node/@opentelemetry/instrumentation-ioredis": ["@opentelemetry/instrumentation-ioredis@0.50.1", "", { "dependencies": { "@opentelemetry/instrumentation": "^0.202.0", "@opentelemetry/redis-common": "^0.38.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-HKrWKOM23qNwqNjWfzkw7mePversmcH5ac6T1dUdiRyJVYaLr4qfydyYkgKIGWHOF2TKvQGobXo3CjvxABQWVw=="],
"@opentelemetry/exporter-logs-otlp-grpc/@opentelemetry/core": ["@opentelemetry/core@2.0.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw=="],
@@ -5260,10 +5424,14 @@
"@prisma/instrumentation/@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.207.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.207.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA=="],
"@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
"@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
"@radix-ui/react-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
"@radix-ui/react-form/@radix-ui/react-label": ["@radix-ui/react-label@2.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ=="],
"@radix-ui/react-label/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="],
"@radix-ui/react-menu/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
@@ -5276,6 +5444,8 @@
"@radix-ui/react-separator/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="],
"@radix-ui/react-toolbar/@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA=="],
"@radix-ui/react-tooltip/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
"@reduxjs/toolkit/immer": ["immer@11.1.4", "", {}, "sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw=="],
@@ -5400,6 +5570,8 @@
"@tanstack/router-plugin/unplugin": ["unplugin@2.3.11", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww=="],
"@tanstack/router-utils/ansis": ["ansis@4.2.0", "", {}, "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig=="],
"@tanstack/start-plugin-core/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
"@tanstack/start-plugin-core/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.40", "", {}, "sha512-s3GeJKSQOwBlzdUrj4ISjJj5SfSh+aqn0wjOar4Bx95iV1ETI7F6S/5hLcfAxZ9kXDcyrAkxPlqmd1ZITttf+w=="],
@@ -5454,6 +5626,8 @@
"accepts/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
"aggregate-error/clean-stack": ["clean-stack@4.2.0", "", { "dependencies": { "escape-string-regexp": "5.0.0" } }, "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg=="],
"ajv-errors/ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="],
"ajv-formats/ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="],
@@ -5500,6 +5674,8 @@
"cacheable-request/mimic-response": ["mimic-response@4.0.0", "", {}, "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg=="],
"checkout/@tanstack/react-query": ["@tanstack/react-query@5.90.21", "", { "dependencies": { "@tanstack/query-core": "5.90.20" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg=="],
"checkout/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
"checkout/@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
@@ -5520,6 +5696,8 @@
"chevrotain-allstar/chevrotain": ["chevrotain@11.0.3", "", { "dependencies": { "@chevrotain/cst-dts-gen": "11.0.3", "@chevrotain/gast": "11.0.3", "@chevrotain/regexp-to-ast": "11.0.3", "@chevrotain/types": "11.0.3", "@chevrotain/utils": "11.0.3", "lodash-es": "4.17.21" } }, "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw=="],
"clean-stack/escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
"cli-truncate/slice-ansi": ["slice-ansi@5.0.0", "", { "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" } }, "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ=="],
"cliui/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
@@ -5586,6 +5764,8 @@
"figures/is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="],
"filelist/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
"finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
"fix-dts-default-cjs-exports/magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
@@ -5604,6 +5784,8 @@
"get-uri/data-uri-to-buffer": ["data-uri-to-buffer@6.0.2", "", {}, "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw=="],
"globby/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"google-auth-library/gaxios": ["gaxios@7.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2", "rimraf": "^5.0.1" } }, "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ=="],
"google-auth-library/gcp-metadata": ["gcp-metadata@8.1.2", "", { "dependencies": { "gaxios": "^7.0.0", "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" } }, "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg=="],
@@ -5624,6 +5806,8 @@
"is-online/p-timeout": ["p-timeout@5.1.0", "", {}, "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew=="],
"is-wsl/is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="],
"katex/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="],
"langchain/uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="],
@@ -5636,12 +5820,18 @@
"langsmith/uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="],
"libsql/detect-libc": ["detect-libc@2.0.2", "", {}, "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="],
"light-my-request/cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
"light-my-request/process-warning": ["process-warning@4.0.1", "", {}, "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q=="],
"listr2/cli-truncate": ["cli-truncate@5.1.1", "", { "dependencies": { "slice-ansi": "^7.1.0", "string-width": "^8.0.0" } }, "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A=="],
"log-symbols/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"log-update/cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="],
"md-to-react-email/marked": ["marked@7.0.4", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-t8eP0dXRJMtMvBojtkcsA7n48BkauktUKzfkPSCq85ZMTJ0v76Rke4DYz01omYpPTUh4p/f7HePgRo3ebG8+QQ=="],
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
@@ -5730,6 +5920,12 @@
"puppeteer/puppeteer-core": ["puppeteer-core@22.14.0", "", { "dependencies": { "@puppeteer/browsers": "2.3.0", "chromium-bidi": "0.6.2", "debug": "^4.3.5", "devtools-protocol": "0.0.1312386", "ws": "^8.18.0" } }, "sha512-rl4tOY5LcA3e374GAlsGGHc05HL3eGNf5rZ+uxkl6id9zVZKcwcp1Z+Nd6byb6WPiPeecT/dwz8f/iUm+AZQSw=="],
"radix-ui/@radix-ui/react-label": ["@radix-ui/react-label@2.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ=="],
"radix-ui/@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA=="],
"radix-ui/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
"rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
"react-day-picker/date-fns": ["date-fns@3.6.0", "", {}, "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww=="],
@@ -5804,12 +6000,18 @@
"tar/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
"ts-to-zod/@clack/prompts": ["@clack/prompts@1.0.0-alpha.4", "", { "dependencies": { "@clack/core": "1.0.0-alpha.4", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-KnmtDF2xQGoI5AlBme9akHtvCRV0RKAARUXHBQO2tMwnY8B08/4zPWigT7uLK25UPrMCEqnyQPkKRjNdhPbf8g=="],
"ts-to-zod/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
"tsc-alias/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
"tsc-alias/commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="],
"tshy/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
"tsutils/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="],
"type-is/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
"unbzip2-stream/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
@@ -5826,6 +6028,8 @@
"wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"wsl-utils/is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="],
"yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"@anthropic-ai/sdk/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
@@ -6142,6 +6346,8 @@
"@langchain/langgraph-sdk/p-queue/p-timeout": ["p-timeout@7.0.1", "", {}, "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg=="],
"@libsql/hrana-client/node-fetch/data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="],
"@mintlify/cli/ink/@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.5", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw=="],
"@mintlify/cli/ink/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
@@ -6328,6 +6534,18 @@
"@modelcontextprotocol/sdk/raw-body/iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
"@oclif/core/ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="],
"@oclif/core/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"@oclif/core/string-width/is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
"@oclif/core/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"@oclif/core/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@oclif/core/wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"@opentelemetry/instrumentation-ioredis/@opentelemetry/instrumentation/@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.208.0", "", { "dependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg=="],
"@opentelemetry/instrumentation-ioredis/@opentelemetry/instrumentation/import-in-the-middle": ["import-in-the-middle@2.0.6", "", { "dependencies": { "acorn": "^8.15.0", "acorn-import-attributes": "^1.9.5", "cjs-module-lexer": "^2.2.0", "module-details-from-path": "^1.0.4" } }, "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw=="],
@@ -6412,12 +6630,12 @@
"better-opn/open/is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="],
"better-opn/open/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="],
"body-parser/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"c12/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="],
"checkout/@tanstack/react-query/@tanstack/query-core": ["@tanstack/query-core@5.90.20", "", {}, "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg=="],
"checkout/@vitejs/plugin-react/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.3", "", {}, "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q=="],
"checkout/@vitejs/plugin-react/react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="],
@@ -6532,10 +6750,14 @@
"langsmith/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
"listr2/cli-truncate/string-width": ["string-width@8.1.1", "", { "dependencies": { "get-east-asian-width": "^1.3.0", "strip-ansi": "^7.1.0" } }, "sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw=="],
"log-symbols/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"log-symbols/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
"log-update/cli-cursor/restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="],
"mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
"next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
@@ -6632,6 +6854,8 @@
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"ts-to-zod/@clack/prompts/@clack/core": ["@clack/core@1.0.0-alpha.4", "", { "dependencies": { "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-VCtU+vjyKPMSakVrB9q1bOnXN7QW/w4+YQDQCOF59GrzydW+169i0fVx/qzRRXJgt8KGj/pZZ/JxXroFZIDByg=="],
"tsc-alias/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"tsc-alias/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
@@ -6898,6 +7122,10 @@
"@modelcontextprotocol/sdk/express/type-is/media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
"@oclif/core/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"@oclif/core/wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"@opentelemetry/instrumentation-ioredis/@opentelemetry/instrumentation/import-in-the-middle/cjs-module-lexer": ["cjs-module-lexer@2.2.0", "", {}, "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ=="],
"@prisma/instrumentation/@opentelemetry/instrumentation/import-in-the-middle/cjs-module-lexer": ["cjs-module-lexer@2.2.0", "", {}, "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ=="],
@@ -6922,6 +7150,10 @@
"gtoken/gaxios/node-fetch/data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="],
"log-update/cli-cursor/restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
"log-update/cli-cursor/restore-cursor/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
"nodemon/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"ora/cli-cursor/restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
@@ -6946,6 +7178,8 @@
"sdk-test/next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"shadcn/open/wsl-utils/is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="],
"tsc-alias/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"tshy/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],

View File

@@ -3,7 +3,7 @@ info:
title: CodeSamples overlay for python target
version: 0.0.0
actions:
- target: $["paths"]["/v1/attach"]["post"]
- target: $["paths"]["/v1/balances.check"]["post"]
update:
x-codeSamples:
- lang: python
@@ -17,7 +17,151 @@ actions:
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.billing.attach(product_id="<id>", redirect_mode="always")
res = autumn.balances.check(customer_id="<id>")
# Handle response
print(res)
- target: $["paths"]["/v1/balances.create"]["post"]
update:
x-codeSamples:
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.balances.create(feature_id="<id>", customer_id="<id>")
# Handle response
print(res)
- target: $["paths"]["/v1/balances.track"]["post"]
update:
x-codeSamples:
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.balances.track(customer_id="<id>")
# Handle response
print(res)
- target: $["paths"]["/v1/balances.update"]["post"]
update:
x-codeSamples:
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.balances.update(customer_id="<id>", feature_id="<id>")
# Handle response
print(res)
- target: $["paths"]["/v1/billing.attach"]["post"]
update:
x-codeSamples:
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.billing.attach(customer_id="<id>", plan_id="<id>", redirect_mode="always")
# Handle response
print(res)
- target: $["paths"]["/v1/billing.preview_attach"]["post"]
update:
x-codeSamples:
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.billing.preview_attach(customer_id="<id>", plan_id="<id>", redirect_mode="always")
# Handle response
print(res)
- target: $["paths"]["/v1/billing.preview_update"]["post"]
update:
x-codeSamples:
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.billing.preview_update(customer_id="<id>")
# Handle response
print(res)
- target: $["paths"]["/v1/billing.setup_payment"]["post"]
update:
x-codeSamples:
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.billing.setup_payment(customer_id="<id>")
# Handle response
print(res)
- target: $["paths"]["/v1/billing.update"]["post"]
update:
x-codeSamples:
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.billing.update(customer_id="<id>")
# Handle response
print(res)
@@ -39,7 +183,7 @@ actions:
# Handle response
print(res)
- target: $["paths"]["/v1/customers.getOrCreate"]["post"]
- target: $["paths"]["/v1/customers.get_or_create"]["post"]
update:
x-codeSamples:
- lang: python
@@ -93,7 +237,7 @@ actions:
# Handle response
print(res)
- target: $["paths"]["/v1/products"]["get"]
- target: $["paths"]["/v1/plans.list"]["post"]
update:
x-codeSamples:
- lang: python

File diff suppressed because it is too large Load Diff

View File

@@ -30,7 +30,7 @@ generation:
generateNewTests: true
skipResponseBodyAssertions: false
python:
version: 0.2.10
version: 0.2.21
additionalDependencies:
dev: {}
main: {}

View File

@@ -198,20 +198,33 @@ with Autumn(
<details open>
<summary>Available methods</summary>
### [Balances](docs/sdks/balancessdk/README.md)
* [create](docs/sdks/balancessdk/README.md#create) - Create a balance for a customer feature.
* [update](docs/sdks/balancessdk/README.md#update) - Update a customer balance.
* [check](docs/sdks/balancessdk/README.md#check) - Check whether usage is allowed for a customer feature.
* [track](docs/sdks/balancessdk/README.md#track) - Track usage for a customer feature.
### [Billing](docs/sdks/billing/README.md)
* [attach](docs/sdks/billing/README.md#attach)
* [attach](docs/sdks/billing/README.md#attach) - Attaches a plan to a customer. Handles new subscriptions, upgrades and downgrades.
* [preview_attach](docs/sdks/billing/README.md#preview_attach) - Preview billing changes before attaching a plan.
* [update](docs/sdks/billing/README.md#update) - Update an existing subscription.
* [preview_update](docs/sdks/billing/README.md#preview_update) - Preview billing changes before updating a subscription.
* [setup_payment](docs/sdks/billing/README.md#setup_payment) - Create a setup payment session for a customer.
### [Customers](docs/sdks/customers/README.md)
* [get_or_create](docs/sdks/customers/README.md#get_or_create) - Creates a customer if they do not exist, or returns the existing customer by your external customer ID.
Use this as the primary entrypoint before billing operations so the customer record is always present and up to date.
* [list](docs/sdks/customers/README.md#list) - Lists customers with pagination and optional filters.
* [update](docs/sdks/customers/README.md#update) - Updates an existing customer by ID.
* [delete](docs/sdks/customers/README.md#delete) - Deletes a customer by ID.
### [Plans](docs/sdks/plans/README.md)
* [list](docs/sdks/plans/README.md#list) - List Plans
* [list](docs/sdks/plans/README.md#list) - List all plans
</details>
<!-- End Available Resources and Operations [operations] -->

View File

@@ -1,10 +0,0 @@
# AttachFreeTrial
## Fields
| Field | Type | Required | Description |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| `length` | *float* | :heavy_check_mark: | N/A |
| `duration` | [models.Duration](../models/duration.md) | :heavy_check_mark: | N/A |
| `card_required` | *Optional[bool]* | :heavy_minus_sign: | N/A |

View File

@@ -1,18 +0,0 @@
# AttachItem
## Fields
| Field | Type | Required | Description |
| ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `type` | [OptionalNullable[models.AttachType]](../models/attachtype.md) | :heavy_minus_sign: | The type of the product item. |
| `feature_id` | *OptionalNullable[str]* | :heavy_minus_sign: | The feature ID of the product item. Should be null for fixed price items. |
| `included_usage` | [OptionalNullable[models.IncludedUsage]](../models/includedusage.md) | :heavy_minus_sign: | The amount of usage included for this feature (per interval). |
| `interval` | [OptionalNullable[models.AttachInterval]](../models/attachinterval.md) | :heavy_minus_sign: | The reset or billing interval of the product item. If null, feature will have no reset date, and if there's a price, it will be billed one-off. |
| `interval_count` | *OptionalNullable[float]* | :heavy_minus_sign: | Interval count of the feature. |
| `entity_feature_id` | *OptionalNullable[str]* | :heavy_minus_sign: | The feature ID of the entity (like seats) to track sub-balances for. |
| `usage_model` | [OptionalNullable[models.UsageModel]](../models/usagemodel.md) | :heavy_minus_sign: | Whether the feature should be prepaid upfront or billed for how much they use end of billing period. |
| `price` | *OptionalNullable[float]* | :heavy_minus_sign: | The price of the product item. Should be null if tiered pricing is set. |
| `tiers` | List[[models.Tiers](../models/tiers.md)] | :heavy_minus_sign: | Tiered pricing for the product item. Not applicable for fixed price items. |
| `billing_units` | *OptionalNullable[float]* | :heavy_minus_sign: | The billing units of the product item (eg $1 for 30 credits). |
| `reset_usage_when_enabled` | *OptionalNullable[bool]* | :heavy_minus_sign: | Whether the usage should be reset when the product is enabled. |

View File

@@ -1,23 +0,0 @@
# AttachRequest
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| `entity_id` | *OptionalNullable[str]* | :heavy_minus_sign: | N/A |
| `entity_data` | [Optional[models.EntityData]](../models/entitydata.md) | :heavy_minus_sign: | N/A |
| `options` | List[[models.Options](../models/options.md)] | :heavy_minus_sign: | N/A |
| `version` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `free_trial` | [OptionalNullable[models.AttachFreeTrial]](../models/attachfreetrial.md) | :heavy_minus_sign: | N/A |
| `items` | List[[models.AttachItem](../models/attachitem.md)] | :heavy_minus_sign: | N/A |
| `product_id` | *str* | :heavy_check_mark: | N/A |
| `invoice` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `enable_product_immediately` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `finalize_invoice` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `redirect_mode` | [Optional[models.RedirectMode]](../models/redirectmode.md) | :heavy_minus_sign: | N/A |
| `success_url` | *Optional[str]* | :heavy_minus_sign: | N/A |
| `new_billing_subscription` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `plan_schedule` | [Optional[models.PlanSchedule]](../models/planschedule.md) | :heavy_minus_sign: | N/A |
| `billing_behavior` | [Optional[models.BillingBehavior]](../models/billingbehavior.md) | :heavy_minus_sign: | N/A |
| `adjustable_quantity` | *Optional[bool]* | :heavy_minus_sign: | N/A |

View File

@@ -1,14 +0,0 @@
# AttachResponse
OK
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- |
| `customer_id` | *str* | :heavy_check_mark: | N/A |
| `entity_id` | *Optional[str]* | :heavy_minus_sign: | N/A |
| `invoice` | [Optional[models.AttachInvoice]](../models/attachinvoice.md) | :heavy_minus_sign: | N/A |
| `payment_url` | *Nullable[str]* | :heavy_check_mark: | N/A |
| `required_action` | [Optional[models.RequiredAction]](../models/requiredaction.md) | :heavy_minus_sign: | N/A |

View File

@@ -5,6 +5,7 @@
| Field | Type | Required | Description |
| ---------------------------------------------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------- |
| `object` | *Literal["balance"]* | :heavy_check_mark: | N/A |
| `feature_id` | *str* | :heavy_check_mark: | N/A |
| `feature` | [Optional[models.CustomerFeature]](../models/customerfeature.md) | :heavy_minus_sign: | N/A |
| `granted` | *float* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,19 @@
# BalancesCheckBalance
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `object` | *Literal["balance"]* | :heavy_check_mark: | N/A |
| `feature_id` | *str* | :heavy_check_mark: | N/A |
| `feature` | [Optional[models.BalancesCheckFeature]](../models/balancescheckfeature.md) | :heavy_minus_sign: | N/A |
| `granted` | *float* | :heavy_check_mark: | N/A |
| `remaining` | *float* | :heavy_check_mark: | N/A |
| `usage` | *float* | :heavy_check_mark: | N/A |
| `unlimited` | *bool* | :heavy_check_mark: | N/A |
| `overage_allowed` | *bool* | :heavy_check_mark: | N/A |
| `max_purchase` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `next_reset_at` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `breakdown` | List[[models.BalancesCheckBreakdown](../models/balancescheckbreakdown.md)] | :heavy_minus_sign: | N/A |
| `rollovers` | List[[models.BalancesCheckBalanceRollover](../models/balancescheckbalancerollover.md)] | :heavy_minus_sign: | N/A |

View File

@@ -1,10 +1,9 @@
# Options
# BalancesCheckBalanceDisplay
## Fields
| Field | Type | Required | Description |
| ----------------------- | ----------------------- | ----------------------- | ----------------------- |
| `feature_id` | *str* | :heavy_check_mark: | N/A |
| `quantity` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `reset_after_trial_end` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `singular` | *OptionalNullable[str]* | :heavy_minus_sign: | N/A |
| `plural` | *OptionalNullable[str]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,16 @@
# BalancesCheckBalanceIntervalEnum
## Values
| Name | Value |
| ------------- | ------------- |
| `ONE_OFF` | one_off |
| `MINUTE` | minute |
| `HOUR` | hour |
| `DAY` | day |
| `WEEK` | week |
| `MONTH` | month |
| `QUARTER` | quarter |
| `SEMI_ANNUAL` | semi_annual |
| `YEAR` | year |

View File

@@ -0,0 +1,9 @@
# BalancesCheckBalanceRollover
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `balance` | *float* | :heavy_check_mark: | N/A |
| `expires_at` | *float* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,17 @@
# BalancesCheckBalanceTo
## Supported Types
### `float`
```python
value: float = /* values here */
```
### `str`
```python
value: str = /* values here */
```

View File

@@ -0,0 +1,10 @@
# BalancesCheckBalanceType
## Values
| Name | Value |
| --------------- | --------------- |
| `BOOLEAN` | boolean |
| `METERED` | metered |
| `CREDIT_SYSTEM` | credit_system |

View File

@@ -0,0 +1,9 @@
# BalancesCheckBillingMethod
## Values
| Name | Value |
| ------------- | ------------- |
| `PREPAID` | prepaid |
| `USAGE_BASED` | usage_based |

View File

@@ -0,0 +1,18 @@
# BalancesCheckBreakdown
## Fields
| Field | Type | Required | Description |
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| `object` | *Literal["balance_breakdown"]* | :heavy_check_mark: | N/A |
| `id` | *Optional[str]* | :heavy_minus_sign: | N/A |
| `plan_id` | *Nullable[str]* | :heavy_check_mark: | N/A |
| `included_grant` | *float* | :heavy_check_mark: | N/A |
| `prepaid_grant` | *float* | :heavy_check_mark: | N/A |
| `remaining` | *float* | :heavy_check_mark: | N/A |
| `usage` | *float* | :heavy_check_mark: | N/A |
| `unlimited` | *bool* | :heavy_check_mark: | N/A |
| `reset` | [Nullable[models.BalancesCheckReset]](../models/balancescheckreset.md) | :heavy_check_mark: | N/A |
| `price` | [Nullable[models.BalancesCheckPrice]](../models/balancescheckprice.md) | :heavy_check_mark: | N/A |
| `expires_at` | *Nullable[float]* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,9 @@
# BalancesCheckCreditSchema
## Fields
| Field | Type | Required | Description |
| -------------------- | -------------------- | -------------------- | -------------------- |
| `metered_feature_id` | *str* | :heavy_check_mark: | N/A |
| `credit_cost` | *float* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,11 @@
# BalancesCheckEnv
The environment of the product
## Values
| Name | Value |
| --------- | --------- |
| `SANDBOX` | sandbox |
| `LIVE` | live |

View File

@@ -0,0 +1,15 @@
# BalancesCheckFeature
## Fields
| Field | Type | Required | Description |
| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `id` | *str* | :heavy_check_mark: | N/A |
| `name` | *str* | :heavy_check_mark: | N/A |
| `type` | [models.BalancesCheckBalanceType](../models/balancescheckbalancetype.md) | :heavy_check_mark: | N/A |
| `consumable` | *bool* | :heavy_check_mark: | N/A |
| `event_names` | List[*str*] | :heavy_minus_sign: | N/A |
| `credit_schema` | List[[models.BalancesCheckCreditSchema](../models/balancescheckcreditschema.md)] | :heavy_minus_sign: | N/A |
| `display` | [Optional[models.BalancesCheckBalanceDisplay]](../models/balancescheckbalancedisplay.md) | :heavy_minus_sign: | N/A |
| `archived` | *bool* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,12 @@
# BalancesCheckFreeTrial
## Fields
| Field | Type | Required | Description |
| ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `duration` | [models.FreeTrialDuration](../models/freetrialduration.md) | :heavy_check_mark: | The duration type of the free trial |
| `length` | *float* | :heavy_check_mark: | The length of the duration type specified |
| `unique_fingerprint` | *bool* | :heavy_check_mark: | Whether the free trial is limited to one per customer fingerprint |
| `card_required` | *bool* | :heavy_check_mark: | Whether the free trial requires a card. If false, the customer can attach the product without going through a checkout flow or having a card on file. |
| `trial_available` | *OptionalNullable[bool]* | :heavy_minus_sign: | Used in customer context. Whether the free trial is available for the customer if they were to attach the product. |

View File

@@ -1,4 +1,4 @@
# AttachGlobals
# BalancesCheckGlobals
## Fields

View File

@@ -0,0 +1,17 @@
# BalancesCheckIntervalUnion
## Supported Types
### `models.BalancesCheckBalanceIntervalEnum`
```python
value: models.BalancesCheckBalanceIntervalEnum = /* values here */
```
### `str`
```python
value: str = /* values here */
```

View File

@@ -0,0 +1,25 @@
# BalancesCheckItem
Product item defining features and pricing within a product
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `type` | [OptionalNullable[models.ProductType]](../models/producttype.md) | :heavy_minus_sign: | The type of the product item |
| `feature_id` | *OptionalNullable[str]* | :heavy_minus_sign: | The feature ID of the product item. If the item is a fixed price, should be `null` |
| `feature_type` | [OptionalNullable[models.FeatureType]](../models/featuretype.md) | :heavy_minus_sign: | Single use features are used once and then depleted, like API calls or credits. Continuous use features are those being used on an ongoing-basis, like storage or seats. |
| `included_usage` | [OptionalNullable[models.IncludedUsage]](../models/includedusage.md) | :heavy_minus_sign: | The amount of usage included for this feature. |
| `interval` | [OptionalNullable[models.ProductInterval]](../models/productinterval.md) | :heavy_minus_sign: | The reset or billing interval of the product item. If null, feature will have no reset date, and if there's a price, it will be billed one-off. |
| `interval_count` | *OptionalNullable[float]* | :heavy_minus_sign: | The interval count of the product item. |
| `price` | *OptionalNullable[float]* | :heavy_minus_sign: | The price of the product item. Should be `null` if tiered pricing is set. |
| `tiers` | List[[models.Tiers](../models/tiers.md)] | :heavy_minus_sign: | Tiered pricing for the product item. Not applicable for fixed price items. |
| `usage_model` | [OptionalNullable[models.UsageModel]](../models/usagemodel.md) | :heavy_minus_sign: | Whether the feature should be prepaid upfront or billed for how much they use end of billing period. |
| `billing_units` | *OptionalNullable[float]* | :heavy_minus_sign: | The amount per billing unit (eg. $9 / 250 units) |
| `reset_usage_when_enabled` | *OptionalNullable[bool]* | :heavy_minus_sign: | Whether the usage should be reset when the product is enabled. |
| `entity_feature_id` | *OptionalNullable[str]* | :heavy_minus_sign: | The entity feature ID of the product item if applicable. |
| `display` | [OptionalNullable[models.ProductDisplay]](../models/productdisplay.md) | :heavy_minus_sign: | The display of the product item. |
| `quantity` | *OptionalNullable[float]* | :heavy_minus_sign: | Used in customer context. Quantity of the feature the customer has prepaid for. |
| `next_cycle_quantity` | *OptionalNullable[float]* | :heavy_minus_sign: | Used in customer context. Quantity of the feature the customer will prepay for in the next cycle. |
| `config` | [OptionalNullable[models.Config]](../models/config.md) | :heavy_minus_sign: | Configuration for rollover and proration behavior of the feature. |

View File

@@ -0,0 +1,12 @@
# BalancesCheckOnDecrease
## Values
| Name | Value |
| --------------------- | --------------------- |
| `PRORATE` | prorate |
| `PRORATE_IMMEDIATELY` | prorate_immediately |
| `PRORATE_NEXT_CYCLE` | prorate_next_cycle |
| `NONE` | none |
| `NO_PRORATIONS` | no_prorations |

View File

@@ -0,0 +1,11 @@
# BalancesCheckOnIncrease
## Values
| Name | Value |
| --------------------- | --------------------- |
| `BILL_IMMEDIATELY` | bill_immediately |
| `PRORATE_IMMEDIATELY` | prorate_immediately |
| `PRORATE_NEXT_CYCLE` | prorate_next_cycle |
| `BILL_NEXT_CYCLE` | bill_next_cycle |

View File

@@ -0,0 +1,12 @@
# BalancesCheckPrice
## Fields
| Field | Type | Required | Description |
| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `amount` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `tiers` | List[[models.BalancesCheckTier](../models/balanceschecktier.md)] | :heavy_minus_sign: | N/A |
| `billing_units` | *float* | :heavy_check_mark: | N/A |
| `billing_method` | [models.BalancesCheckBillingMethod](../models/balancescheckbillingmethod.md) | :heavy_check_mark: | N/A |
| `max_purchase` | *Nullable[float]* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,16 @@
# BalancesCheckRequest
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `customer_id` | *str* | :heavy_check_mark: | ID which you provided when creating the customer |
| `feature_id` | *Optional[str]* | :heavy_minus_sign: | N/A |
| `entity_id` | *Optional[str]* | :heavy_minus_sign: | If using entity balances (eg, seats), the entity ID to check access for. |
| `required_balance` | *Optional[float]* | :heavy_minus_sign: | If you know the amount of the feature the end user is consuming in advance. If their balance is below this quantity, allowed will be false. |
| `properties` | Dict[str, *Any*] | :heavy_minus_sign: | N/A |
| `send_event` | *Optional[bool]* | :heavy_minus_sign: | If true, a usage event will be recorded together with checking access. The required_balance field will be used as the usage value. |
| `with_preview` | *Optional[bool]* | :heavy_minus_sign: | If true, the response will include a preview object, which can be used to display information such as a paywall or upgrade confirmation. |
| `product_id` | *Optional[str]* | :heavy_minus_sign: | N/A |
| `required_quantity` | *Optional[float]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,10 @@
# BalancesCheckReset
## Fields
| Field | Type | Required | Description |
| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `interval` | [models.BalancesCheckIntervalUnion](../models/balancescheckintervalunion.md) | :heavy_check_mark: | N/A |
| `interval_count` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `resets_at` | *Nullable[float]* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,15 @@
# BalancesCheckResponse
OK
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| `allowed` | *bool* | :heavy_check_mark: | N/A |
| `customer_id` | *str* | :heavy_check_mark: | N/A |
| `entity_id` | *OptionalNullable[str]* | :heavy_minus_sign: | N/A |
| `required_balance` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `balance` | [Nullable[models.BalancesCheckBalance]](../models/balancescheckbalance.md) | :heavy_check_mark: | N/A |
| `preview` | [Optional[models.Preview]](../models/preview.md) | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,9 @@
# BalancesCheckScenario
## Values
| Name | Value |
| -------------- | -------------- |
| `USAGE_LIMIT` | usage_limit |
| `FEATURE_FLAG` | feature_flag |

View File

@@ -0,0 +1,9 @@
# BalancesCheckTier
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `to` | [models.BalancesCheckBalanceTo](../models/balancescheckbalanceto.md) | :heavy_check_mark: | N/A |
| `amount` | *float* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,8 @@
# BalancesCreateGlobals
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `x_api_version` | *Optional[str]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,16 @@
# BalancesCreateInterval
## Values
| Name | Value |
| ------------- | ------------- |
| `ONE_OFF` | one_off |
| `MINUTE` | minute |
| `HOUR` | hour |
| `DAY` | day |
| `WEEK` | week |
| `MONTH` | month |
| `QUARTER` | quarter |
| `SEMI_ANNUAL` | semi_annual |
| `YEAR` | year |

View File

@@ -0,0 +1,15 @@
# BalancesCreateRequest
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| `feature_id` | *str* | :heavy_check_mark: | The feature ID to create the balance for |
| `customer_id` | *str* | :heavy_check_mark: | The customer ID to assign the balance to |
| `entity_id` | *Optional[str]* | :heavy_minus_sign: | Entity ID for entity-scoped balances |
| `included` | *Optional[float]* | :heavy_minus_sign: | The initial balance amount to grant |
| `unlimited` | *Optional[bool]* | :heavy_minus_sign: | Whether the balance is unlimited |
| `reset` | [Optional[models.BalancesCreateReset]](../models/balancescreatereset.md) | :heavy_minus_sign: | Reset configuration for the balance |
| `expires_at` | *Optional[float]* | :heavy_minus_sign: | Unix timestamp (milliseconds) when the balance expires |
| `granted_balance` | *Optional[float]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,11 @@
# BalancesCreateReset
Reset configuration for the balance
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `interval` | [models.BalancesCreateInterval](../models/balancescreateinterval.md) | :heavy_check_mark: | N/A |
| `interval_count` | *Optional[float]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,10 @@
# BalancesCreateResponse
OK
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `success` | *bool* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,19 @@
# BalancesTrackBalance
## Fields
| Field | Type | Required | Description |
| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `object` | *Literal["balance"]* | :heavy_check_mark: | N/A |
| `feature_id` | *str* | :heavy_check_mark: | N/A |
| `feature` | [Optional[models.BalancesTrackBalanceFeature]](../models/balancestrackbalancefeature.md) | :heavy_minus_sign: | N/A |
| `granted` | *float* | :heavy_check_mark: | N/A |
| `remaining` | *float* | :heavy_check_mark: | N/A |
| `usage` | *float* | :heavy_check_mark: | N/A |
| `unlimited` | *bool* | :heavy_check_mark: | N/A |
| `overage_allowed` | *bool* | :heavy_check_mark: | N/A |
| `max_purchase` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `next_reset_at` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `breakdown` | List[[models.BalancesTrackBalanceBreakdown](../models/balancestrackbalancebreakdown.md)] | :heavy_minus_sign: | N/A |
| `rollovers` | List[[models.BalancesTrackBalanceRollover](../models/balancestrackbalancerollover.md)] | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,9 @@
# BalancesTrackBalanceBillingMethod
## Values
| Name | Value |
| ------------- | ------------- |
| `PREPAID` | prepaid |
| `USAGE_BASED` | usage_based |

View File

@@ -0,0 +1,18 @@
# BalancesTrackBalanceBreakdown
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ |
| `object` | *Literal["balance_breakdown"]* | :heavy_check_mark: | N/A |
| `id` | *Optional[str]* | :heavy_minus_sign: | N/A |
| `plan_id` | *Nullable[str]* | :heavy_check_mark: | N/A |
| `included_grant` | *float* | :heavy_check_mark: | N/A |
| `prepaid_grant` | *float* | :heavy_check_mark: | N/A |
| `remaining` | *float* | :heavy_check_mark: | N/A |
| `usage` | *float* | :heavy_check_mark: | N/A |
| `unlimited` | *bool* | :heavy_check_mark: | N/A |
| `reset` | [Nullable[models.BalancesTrackBalanceReset]](../models/balancestrackbalancereset.md) | :heavy_check_mark: | N/A |
| `price` | [Nullable[models.BalancesTrackBalancePrice]](../models/balancestrackbalanceprice.md) | :heavy_check_mark: | N/A |
| `expires_at` | *Nullable[float]* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,9 @@
# BalancesTrackBalanceCreditSchema
## Fields
| Field | Type | Required | Description |
| -------------------- | -------------------- | -------------------- | -------------------- |
| `metered_feature_id` | *str* | :heavy_check_mark: | N/A |
| `credit_cost` | *float* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,9 @@
# BalancesTrackBalanceDisplay
## Fields
| Field | Type | Required | Description |
| ----------------------- | ----------------------- | ----------------------- | ----------------------- |
| `singular` | *OptionalNullable[str]* | :heavy_minus_sign: | N/A |
| `plural` | *OptionalNullable[str]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,15 @@
# BalancesTrackBalanceFeature
## Fields
| Field | Type | Required | Description |
| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `id` | *str* | :heavy_check_mark: | N/A |
| `name` | *str* | :heavy_check_mark: | N/A |
| `type` | [models.BalancesTrackBalanceType](../models/balancestrackbalancetype.md) | :heavy_check_mark: | N/A |
| `consumable` | *bool* | :heavy_check_mark: | N/A |
| `event_names` | List[*str*] | :heavy_minus_sign: | N/A |
| `credit_schema` | List[[models.BalancesTrackBalanceCreditSchema](../models/balancestrackbalancecreditschema.md)] | :heavy_minus_sign: | N/A |
| `display` | [Optional[models.BalancesTrackBalanceDisplay]](../models/balancestrackbalancedisplay.md) | :heavy_minus_sign: | N/A |
| `archived` | *bool* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,16 @@
# BalancesTrackBalanceIntervalEnum
## Values
| Name | Value |
| ------------- | ------------- |
| `ONE_OFF` | one_off |
| `MINUTE` | minute |
| `HOUR` | hour |
| `DAY` | day |
| `WEEK` | week |
| `MONTH` | month |
| `QUARTER` | quarter |
| `SEMI_ANNUAL` | semi_annual |
| `YEAR` | year |

View File

@@ -0,0 +1,17 @@
# BalancesTrackBalanceIntervalUnion
## Supported Types
### `models.BalancesTrackBalanceIntervalEnum`
```python
value: models.BalancesTrackBalanceIntervalEnum = /* values here */
```
### `str`
```python
value: str = /* values here */
```

View File

@@ -0,0 +1,12 @@
# BalancesTrackBalancePrice
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ |
| `amount` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `tiers` | List[[models.BalancesTrackBalanceTier](../models/balancestrackbalancetier.md)] | :heavy_minus_sign: | N/A |
| `billing_units` | *float* | :heavy_check_mark: | N/A |
| `billing_method` | [models.BalancesTrackBalanceBillingMethod](../models/balancestrackbalancebillingmethod.md) | :heavy_check_mark: | N/A |
| `max_purchase` | *Nullable[float]* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,10 @@
# BalancesTrackBalanceReset
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ |
| `interval` | [models.BalancesTrackBalanceIntervalUnion](../models/balancestrackbalanceintervalunion.md) | :heavy_check_mark: | N/A |
| `interval_count` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `resets_at` | *Nullable[float]* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,9 @@
# BalancesTrackBalanceRollover
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `balance` | *float* | :heavy_check_mark: | N/A |
| `expires_at` | *float* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,19 @@
# BalancesTrackBalances
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| `object` | *Literal["balance"]* | :heavy_check_mark: | N/A |
| `feature_id` | *str* | :heavy_check_mark: | N/A |
| `feature` | [Optional[models.BalancesTrackFeature]](../models/balancestrackfeature.md) | :heavy_minus_sign: | N/A |
| `granted` | *float* | :heavy_check_mark: | N/A |
| `remaining` | *float* | :heavy_check_mark: | N/A |
| `usage` | *float* | :heavy_check_mark: | N/A |
| `unlimited` | *bool* | :heavy_check_mark: | N/A |
| `overage_allowed` | *bool* | :heavy_check_mark: | N/A |
| `max_purchase` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `next_reset_at` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `breakdown` | List[[models.BalancesTrackBreakdown](../models/balancestrackbreakdown.md)] | :heavy_minus_sign: | N/A |
| `rollovers` | List[[models.BalancesTrackRollover](../models/balancestrackrollover.md)] | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,9 @@
# BalancesTrackBalanceTier
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `to` | [models.BalancesTrackBalanceTo](../models/balancestrackbalanceto.md) | :heavy_check_mark: | N/A |
| `amount` | *float* | :heavy_check_mark: | N/A |

Some files were not shown because too many files have changed in this diff Show More