finished setup
This commit is contained in:
@@ -13,7 +13,9 @@ import { DynamicResponseExample } from "/components/dynamic-response-example.jsx
|
||||
ID which you provided when creating the customer
|
||||
</DynamicParamField>
|
||||
|
||||
<DynamicParamField body="feature_id" type="string" />
|
||||
<DynamicParamField body="feature_id" type="string" required>
|
||||
ID of the feature to check access to.
|
||||
</DynamicParamField>
|
||||
|
||||
<DynamicParamField body="entity_id" type="string">
|
||||
If using entity balances (eg, seats), the entity ID to check access for.
|
||||
@@ -33,10 +35,6 @@ import { DynamicResponseExample } from "/components/dynamic-response-example.jsx
|
||||
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
|
||||
|
||||
|
||||
@@ -4232,6 +4232,7 @@ paths:
|
||||
description: ID which you provided when creating the customer
|
||||
feature_id:
|
||||
type: string
|
||||
description: ID of the feature to check access to.
|
||||
entity_id:
|
||||
type: string
|
||||
description: If using entity balances (eg, seats), the entity ID to check access
|
||||
@@ -4256,12 +4257,9 @@ paths:
|
||||
description: 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:
|
||||
type: string
|
||||
required_quantity:
|
||||
type: number
|
||||
required:
|
||||
- customer_id
|
||||
- feature_id
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
@@ -4831,6 +4829,7 @@ paths:
|
||||
|
||||
const result = await autumn.balances.check({
|
||||
customerId: "<id>",
|
||||
featureId: "<id>",
|
||||
});
|
||||
- lang: python
|
||||
label: Python (SDK)
|
||||
@@ -4839,7 +4838,10 @@ paths:
|
||||
|
||||
autumn = Autumn(secret_key="am_sk_test...")
|
||||
|
||||
res = autumn.balances.check(customer_id="<id>")
|
||||
res = autumn.balances.check(
|
||||
customer_id="<id>",
|
||||
feature_id="<id>",
|
||||
)
|
||||
/v1/balances.track:
|
||||
post:
|
||||
operationId: balancesTrack
|
||||
|
||||
@@ -64,11 +64,13 @@ export default function UseAutumnScenarioPage() {
|
||||
// Input state
|
||||
const [planId, setPlanId] = useState("");
|
||||
const [featureId, setFeatureId] = useState("");
|
||||
const [requiredBalance, setRequiredBalance] = useState("");
|
||||
const [openInNewTab, setOpenInNewTab] = useState(false);
|
||||
|
||||
// Form element IDs
|
||||
const planIdInputId = useId();
|
||||
const featureIdInputId = useId();
|
||||
const requiredBalanceInputId = useId();
|
||||
|
||||
const runAction = async ({
|
||||
name,
|
||||
@@ -123,10 +125,16 @@ export default function UseAutumnScenarioPage() {
|
||||
|
||||
const handleCheck = () => {
|
||||
if (!featureId) return;
|
||||
const params = {
|
||||
featureId,
|
||||
requiredBalance: requiredBalance
|
||||
? parseFloat(requiredBalance)
|
||||
: undefined,
|
||||
};
|
||||
runAction({
|
||||
name: "check",
|
||||
params: { featureId },
|
||||
execute: () => check({ featureId }),
|
||||
params,
|
||||
execute: () => check(params),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -225,6 +233,22 @@ export default function UseAutumnScenarioPage() {
|
||||
className="h-8 text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<Label
|
||||
htmlFor={requiredBalanceInputId}
|
||||
className="text-xs text-zinc-500"
|
||||
>
|
||||
Required Balance (optional)
|
||||
</Label>
|
||||
<Input
|
||||
id={requiredBalanceInputId}
|
||||
type="number"
|
||||
placeholder="Enter required balance"
|
||||
value={requiredBalance}
|
||||
onChange={(e) => setRequiredBalance(e.target.value)}
|
||||
className="h-8 text-sm"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
size="sm"
|
||||
disabled={isRunning || !featureId}
|
||||
|
||||
@@ -6,6 +6,6 @@ const SIMULATE_UNAUTHENTICATED = false;
|
||||
|
||||
export const handler = autumnHandler({
|
||||
secretKey: process.env.AUTUMN_SECRET_KEY,
|
||||
baseURL: "http://localhost:8080",
|
||||
autumnURL: "http://localhost:8080",
|
||||
identify: async () => (SIMULATE_UNAUTHENTICATED ? null : SDK_TEST_IDENTITY),
|
||||
});
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
"@/*": ["./*"],
|
||||
"@api/*": ["../../shared/api/*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
],
|
||||
"@sdk": ["../../packages/autumn-js/src/sdk/index.ts"],
|
||||
"@sdk/*": ["../../packages/autumn-js/src/sdk/*"],
|
||||
"@api/*": ["../../shared/api/*"],
|
||||
"@utils/*": ["../../packages/autumn-js/src/utils/*"],
|
||||
"autumn-js": ["../../packages/autumn-js/src/sdk/index.ts"],
|
||||
"autumn-js/react": ["../../packages/autumn-js/src/react/index.ts"],
|
||||
|
||||
2
bun.lock
2
bun.lock
@@ -168,7 +168,7 @@
|
||||
},
|
||||
"packages/sdk": {
|
||||
"name": "@useautumn/sdk",
|
||||
"version": "0.8.26",
|
||||
"version": "0.8.27",
|
||||
"dependencies": {
|
||||
"zod": "^3.25.65 || ^4.0.0",
|
||||
},
|
||||
|
||||
@@ -17,7 +17,7 @@ actions:
|
||||
secret_key="<YOUR_BEARER_TOKEN_HERE>",
|
||||
) as autumn:
|
||||
|
||||
res = autumn.balances.check(customer_id="<id>")
|
||||
res = autumn.balances.check(customer_id="<id>", feature_id="<id>")
|
||||
|
||||
# Handle response
|
||||
print(res)
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
lockVersion: 2.0.0
|
||||
id: 05940b80-1ef8-40f4-9878-822fb2792070
|
||||
management:
|
||||
docChecksum: ae28cba9f4a31ec39633cc683b159eab
|
||||
docChecksum: fec27a570216b53ac684c105645b6173
|
||||
docVersion: 2.1.0
|
||||
speakeasyVersion: 1.719.0
|
||||
generationVersion: 2.824.1
|
||||
releaseVersion: 0.2.22
|
||||
configChecksum: 05fe4cc58f958fa21b320a1cbb0ec4d8
|
||||
releaseVersion: 0.2.23
|
||||
configChecksum: b49d9388b24bfc90f604822ef8177d32
|
||||
persistentEdits:
|
||||
generation_id: b8deb3e6-4376-4384-8fb8-d3742769316e
|
||||
pristine_commit_hash: d81074b2463a2168ca16d2be775f9316dbcec5f0
|
||||
pristine_tree_hash: b9f1e436d46ef67a51ccebe4176695d899ea2658
|
||||
generation_id: 7ec28ef9-de11-4ffe-a994-4a2d11fa4783
|
||||
pristine_commit_hash: 1cb483a63d6f596f6074489a6e9910875d391989
|
||||
pristine_tree_hash: 44c77d4ff8b12e187ee9387f45bb54d132266c56
|
||||
features:
|
||||
python:
|
||||
additionalDependencies: 1.0.0
|
||||
@@ -125,8 +125,8 @@ trackedFiles:
|
||||
pristine_git_object: 3e6f66868ff780f866d68fdd7875f51990446172
|
||||
docs/models/balancescheckrequest.md:
|
||||
id: 3f58aa2a0e56
|
||||
last_write_checksum: sha1:da2a911efdfb3247c30564d9b44798ddc1064539
|
||||
pristine_git_object: 88f4b9bd27b9fb0e9438c2b2ee95fb8d115bed5b
|
||||
last_write_checksum: sha1:631eddef8c414fc980bee9b676dced772c276e24
|
||||
pristine_git_object: 426327d989050aa71a9dc1d8e55f1e3b8bc9db4a
|
||||
docs/models/balancescheckreset.md:
|
||||
id: acd256151825
|
||||
last_write_checksum: sha1:aaeb8d3a138366e3c03c7e5c45c7adcb22062190
|
||||
@@ -1465,8 +1465,8 @@ trackedFiles:
|
||||
pristine_git_object: 69dd549ec7f5f885101d08dd502e25748183aebf
|
||||
docs/sdks/balancessdk/README.md:
|
||||
id: 2484f934be2e
|
||||
last_write_checksum: sha1:f7062478c95b5d1942725f202da8591b6997801d
|
||||
pristine_git_object: 367d6f7e6677473533e5ec84423c6b92bb191627
|
||||
last_write_checksum: sha1:a8dd55b3787ac362deacf763b0a211900a767e93
|
||||
pristine_git_object: 7afb196a0fe5d64bbc8f5754febdc70e891f9783
|
||||
docs/sdks/billing/README.md:
|
||||
id: dc915331dd9d
|
||||
last_write_checksum: sha1:e3669a666eb87cb510f80973d756454cb5124433
|
||||
@@ -1489,8 +1489,8 @@ trackedFiles:
|
||||
pristine_git_object: f13c2fb5532a06cfe87f594097bfbf72e8fc04a1
|
||||
pyproject.toml:
|
||||
id: 5d07e7d72637
|
||||
last_write_checksum: sha1:1e1204524034eb1c9c0cbb4327c4ac5ad156a8e4
|
||||
pristine_git_object: 38ecae9bb9c9bd37af5c19d7f6869e1a672f86bc
|
||||
last_write_checksum: sha1:014fd5de1df29b5f35e76f1c635c021ad9a7a03b
|
||||
pristine_git_object: 724b12dd08709c8cddac0a78d200b08ec654fc01
|
||||
scripts/publish.sh:
|
||||
id: fe273b08f514
|
||||
last_write_checksum: sha1:adc9b741c12ad1591ab4870eabe20f0d0a86cd1a
|
||||
@@ -1513,12 +1513,12 @@ trackedFiles:
|
||||
pristine_git_object: 3e604651c1eae73d815b276806e73b2f1334bb79
|
||||
src/autumn_sdk/_version.py:
|
||||
id: a98babfdf4fc
|
||||
last_write_checksum: sha1:956be51e7b757519eedbeb2ff25e3d59b24c8a18
|
||||
pristine_git_object: 6e51775a922b9d5cdbd3cf7c928df326748a5255
|
||||
last_write_checksum: sha1:587361ce6cbd0c8f082cc3835fe408873429de3b
|
||||
pristine_git_object: 657096928db179a673873a7c2970bc56d0134bd9
|
||||
src/autumn_sdk/balances_sdk.py:
|
||||
id: a24aee6f517f
|
||||
last_write_checksum: sha1:991efc1f4a5675c7c69983dc539b419fee18895b
|
||||
pristine_git_object: 458d7a5d63adb489da6bb0292ae672085714e36b
|
||||
last_write_checksum: sha1:92e60f2fca39931ac13bd2e9b76048c307a8393a
|
||||
pristine_git_object: 10dad75191da7d12379beb6db1bce3a49a21361d
|
||||
src/autumn_sdk/basesdk.py:
|
||||
id: 8c9c35fe744d
|
||||
last_write_checksum: sha1:5d6abacbd251bd806538b19ab9662994bbfc6e24
|
||||
@@ -1561,8 +1561,8 @@ trackedFiles:
|
||||
pristine_git_object: ef0446c2af1fb073acd7d9dbded6b04bfad1d0dd
|
||||
src/autumn_sdk/models/balancescheckop.py:
|
||||
id: 27ed9e0d5743
|
||||
last_write_checksum: sha1:f76c84c4592ee5bee854d2d31ac55b589c54d86c
|
||||
pristine_git_object: 3a48eb8b3bda977baaf9afa42abc969e736d649a
|
||||
last_write_checksum: sha1:4c29af4c515b7d7248cb2bac03299483be523d7f
|
||||
pristine_git_object: 23ee9fc6c157d5ed56a335112a7da96dfcee325c
|
||||
src/autumn_sdk/models/balancescreateop.py:
|
||||
id: 8509fb57571f
|
||||
last_write_checksum: sha1:406d57f4df7fb4eba2a7c8f906cf64ff0b31eb2c
|
||||
@@ -1880,7 +1880,7 @@ examples:
|
||||
header:
|
||||
x-api-version: "2.1"
|
||||
requestBody:
|
||||
application/json: {"customer_id": "<id>"}
|
||||
application/json: {"customer_id": "<id>", "feature_id": "<id>"}
|
||||
responses:
|
||||
"200":
|
||||
application/json: {"allowed": true, "customer_id": "<id>", "balance": {"feature_id": "<id>", "granted": 7002.31, "remaining": 9536.21, "usage": 3270.65, "unlimited": false, "overage_allowed": true, "max_purchase": 8252.55, "next_reset_at": 9394.31}}
|
||||
|
||||
@@ -30,7 +30,7 @@ generation:
|
||||
generateNewTests: true
|
||||
skipResponseBodyAssertions: false
|
||||
python:
|
||||
version: 0.2.22
|
||||
version: 0.2.23
|
||||
additionalDependencies:
|
||||
dev: {}
|
||||
main: {}
|
||||
|
||||
@@ -6,11 +6,9 @@
|
||||
| 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 |
|
||||
| `feature_id` | *str* | :heavy_check_mark: | ID of the feature to check access to. |
|
||||
| `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 |
|
||||
| `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. |
|
||||
@@ -121,7 +121,7 @@ with Autumn(
|
||||
secret_key="<YOUR_BEARER_TOKEN_HERE>",
|
||||
) as autumn:
|
||||
|
||||
res = autumn.balances.check(customer_id="<id>")
|
||||
res = autumn.balances.check(customer_id="<id>", feature_id="<id>")
|
||||
|
||||
# Handle response
|
||||
print(res)
|
||||
@@ -133,14 +133,12 @@ with Autumn(
|
||||
| Parameter | 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 |
|
||||
| `feature_id` | *str* | :heavy_check_mark: | ID of the feature to check access to. |
|
||||
| `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 |
|
||||
| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. |
|
||||
|
||||
### Response
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "autumn-sdk"
|
||||
version = "0.2.22"
|
||||
version = "0.2.23"
|
||||
description = "Python SDK for the Autumn billing API"
|
||||
authors = [{ name = "Autumn" },]
|
||||
readme = "README.md"
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
import importlib.metadata
|
||||
|
||||
__title__: str = "autumn-sdk"
|
||||
__version__: str = "0.2.22"
|
||||
__version__: str = "0.2.23"
|
||||
__openapi_doc_version__: str = "2.1.0"
|
||||
__gen_version__: str = "2.824.1"
|
||||
__user_agent__: str = "speakeasy-sdk/python 0.2.22 2.824.1 2.1.0 autumn-sdk"
|
||||
__user_agent__: str = "speakeasy-sdk/python 0.2.23 2.824.1 2.1.0 autumn-sdk"
|
||||
|
||||
try:
|
||||
if __package__ is not None:
|
||||
|
||||
@@ -473,14 +473,12 @@ class BalancesSDK(BaseSDK):
|
||||
self,
|
||||
*,
|
||||
customer_id: str,
|
||||
feature_id: Optional[str] = None,
|
||||
feature_id: str,
|
||||
entity_id: Optional[str] = None,
|
||||
required_balance: Optional[float] = None,
|
||||
properties: Optional[Dict[str, Any]] = None,
|
||||
send_event: Optional[bool] = None,
|
||||
with_preview: Optional[bool] = None,
|
||||
product_id: Optional[str] = None,
|
||||
required_quantity: Optional[float] = None,
|
||||
retries: OptionalNullable[utils.RetryConfig] = UNSET,
|
||||
server_url: Optional[str] = None,
|
||||
timeout_ms: Optional[int] = None,
|
||||
@@ -489,14 +487,12 @@ class BalancesSDK(BaseSDK):
|
||||
r"""Check whether usage is allowed for a customer feature.
|
||||
|
||||
:param customer_id: ID which you provided when creating the customer
|
||||
:param feature_id:
|
||||
:param feature_id: ID of the feature to check access to.
|
||||
:param entity_id: If using entity balances (eg, seats), the entity ID to check access for.
|
||||
:param required_balance: 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.
|
||||
:param properties:
|
||||
:param send_event: If true, a usage event will be recorded together with checking access. The required_balance field will be used as the usage value.
|
||||
:param with_preview: If true, the response will include a preview object, which can be used to display information such as a paywall or upgrade confirmation.
|
||||
:param product_id:
|
||||
:param required_quantity:
|
||||
:param retries: Override the default retry configuration for this method
|
||||
:param server_url: Override the default server URL for this method
|
||||
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
|
||||
@@ -520,8 +516,6 @@ class BalancesSDK(BaseSDK):
|
||||
properties=properties,
|
||||
send_event=send_event,
|
||||
with_preview=with_preview,
|
||||
product_id=product_id,
|
||||
required_quantity=required_quantity,
|
||||
)
|
||||
|
||||
req = self._build_request(
|
||||
@@ -587,14 +581,12 @@ class BalancesSDK(BaseSDK):
|
||||
self,
|
||||
*,
|
||||
customer_id: str,
|
||||
feature_id: Optional[str] = None,
|
||||
feature_id: str,
|
||||
entity_id: Optional[str] = None,
|
||||
required_balance: Optional[float] = None,
|
||||
properties: Optional[Dict[str, Any]] = None,
|
||||
send_event: Optional[bool] = None,
|
||||
with_preview: Optional[bool] = None,
|
||||
product_id: Optional[str] = None,
|
||||
required_quantity: Optional[float] = None,
|
||||
retries: OptionalNullable[utils.RetryConfig] = UNSET,
|
||||
server_url: Optional[str] = None,
|
||||
timeout_ms: Optional[int] = None,
|
||||
@@ -603,14 +595,12 @@ class BalancesSDK(BaseSDK):
|
||||
r"""Check whether usage is allowed for a customer feature.
|
||||
|
||||
:param customer_id: ID which you provided when creating the customer
|
||||
:param feature_id:
|
||||
:param feature_id: ID of the feature to check access to.
|
||||
:param entity_id: If using entity balances (eg, seats), the entity ID to check access for.
|
||||
:param required_balance: 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.
|
||||
:param properties:
|
||||
:param send_event: If true, a usage event will be recorded together with checking access. The required_balance field will be used as the usage value.
|
||||
:param with_preview: If true, the response will include a preview object, which can be used to display information such as a paywall or upgrade confirmation.
|
||||
:param product_id:
|
||||
:param required_quantity:
|
||||
:param retries: Override the default retry configuration for this method
|
||||
:param server_url: Override the default server URL for this method
|
||||
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
|
||||
@@ -634,8 +624,6 @@ class BalancesSDK(BaseSDK):
|
||||
properties=properties,
|
||||
send_event=send_event,
|
||||
with_preview=with_preview,
|
||||
product_id=product_id,
|
||||
required_quantity=required_quantity,
|
||||
)
|
||||
|
||||
req = self._build_request_async(
|
||||
|
||||
@@ -47,7 +47,8 @@ class BalancesCheckGlobals(BaseModel):
|
||||
class BalancesCheckRequestTypedDict(TypedDict):
|
||||
customer_id: str
|
||||
r"""ID which you provided when creating the customer"""
|
||||
feature_id: NotRequired[str]
|
||||
feature_id: str
|
||||
r"""ID of the feature to check access to."""
|
||||
entity_id: NotRequired[str]
|
||||
r"""If using entity balances (eg, seats), the entity ID to check access for."""
|
||||
required_balance: NotRequired[float]
|
||||
@@ -57,15 +58,14 @@ class BalancesCheckRequestTypedDict(TypedDict):
|
||||
r"""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: NotRequired[bool]
|
||||
r"""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: NotRequired[str]
|
||||
required_quantity: NotRequired[float]
|
||||
|
||||
|
||||
class BalancesCheckRequest(BaseModel):
|
||||
customer_id: str
|
||||
r"""ID which you provided when creating the customer"""
|
||||
|
||||
feature_id: Optional[str] = None
|
||||
feature_id: str
|
||||
r"""ID of the feature to check access to."""
|
||||
|
||||
entity_id: Optional[str] = None
|
||||
r"""If using entity balances (eg, seats), the entity ID to check access for."""
|
||||
@@ -81,22 +81,15 @@ class BalancesCheckRequest(BaseModel):
|
||||
with_preview: Optional[bool] = None
|
||||
r"""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] = None
|
||||
|
||||
required_quantity: Optional[float] = None
|
||||
|
||||
@model_serializer(mode="wrap")
|
||||
def serialize_model(self, handler):
|
||||
optional_fields = set(
|
||||
[
|
||||
"feature_id",
|
||||
"entity_id",
|
||||
"required_balance",
|
||||
"properties",
|
||||
"send_event",
|
||||
"with_preview",
|
||||
"product_id",
|
||||
"required_quantity",
|
||||
]
|
||||
)
|
||||
serialized = handler(self)
|
||||
|
||||
2
others/python-sdk/uv.lock
generated
2
others/python-sdk/uv.lock
generated
@@ -44,7 +44,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "autumn-sdk"
|
||||
version = "0.2.22"
|
||||
version = "0.2.23"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "httpcore" },
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import type { Customer } from "@useautumn/sdk";
|
||||
|
||||
type CustomerBalance = Customer["balances"][string];
|
||||
type CustomerFeature = NonNullable<Customer["balances"][string]["feature"]>;
|
||||
|
||||
const getAvailableOverage = ({
|
||||
balance,
|
||||
}: {
|
||||
balance: CustomerBalance;
|
||||
}): number | undefined => {
|
||||
const breakdown = balance.breakdown ?? [];
|
||||
const usageBasedBreakdown = breakdown.filter(
|
||||
(item) => item.price?.billingMethod === "usage_based",
|
||||
);
|
||||
|
||||
if (usageBasedBreakdown.length === 0) {
|
||||
return balance.maxPurchase ?? undefined;
|
||||
}
|
||||
|
||||
let maxOverage = 0;
|
||||
let overageUsage = 0;
|
||||
|
||||
for (const item of usageBasedBreakdown) {
|
||||
if (item.price?.maxPurchase === null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (item.price?.maxPurchase !== undefined) {
|
||||
maxOverage += item.price.maxPurchase;
|
||||
}
|
||||
|
||||
const overage = Math.max(
|
||||
0,
|
||||
item.usage - item.includedGrant - item.prepaidGrant,
|
||||
);
|
||||
overageUsage += overage;
|
||||
}
|
||||
|
||||
return Math.max(0, maxOverage - overageUsage);
|
||||
};
|
||||
|
||||
export const balanceToAllowed = ({
|
||||
balance,
|
||||
feature,
|
||||
requiredBalance,
|
||||
}: {
|
||||
balance: CustomerBalance;
|
||||
feature: CustomerFeature;
|
||||
requiredBalance: number;
|
||||
}) => {
|
||||
if (feature.type === "boolean") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (balance.unlimited) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (requiredBalance < 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (balance.overageAllowed) {
|
||||
const availableOverage = getAvailableOverage({ balance });
|
||||
if (availableOverage === undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return balance.remaining + availableOverage >= requiredBalance;
|
||||
}
|
||||
|
||||
return balance.remaining >= requiredBalance;
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { Customer } from "@useautumn/sdk";
|
||||
|
||||
type CustomerFeature = NonNullable<Customer["balances"][string]["feature"]>;
|
||||
|
||||
export const customerToFeatures = ({
|
||||
customer,
|
||||
}: {
|
||||
customer: Customer;
|
||||
}): CustomerFeature[] => {
|
||||
const balances = Object.values(customer.balances);
|
||||
if (balances.length === 0) return [];
|
||||
|
||||
const firstBalance = balances[0];
|
||||
if (!firstBalance.feature) {
|
||||
throw new Error(
|
||||
"[customerToFeatures] please expand `balances.feature` to get features for the customer",
|
||||
);
|
||||
}
|
||||
|
||||
return balances
|
||||
.map((balance) => balance.feature)
|
||||
.filter((feature): feature is CustomerFeature => Boolean(feature));
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import type { Customer } from "@useautumn/sdk";
|
||||
|
||||
type CustomerFeature = NonNullable<Customer["balances"][string]["feature"]>;
|
||||
|
||||
export const findCreditSystemsByFeature = ({
|
||||
featureId,
|
||||
features,
|
||||
}: {
|
||||
featureId: string;
|
||||
features: CustomerFeature[];
|
||||
}) => {
|
||||
return features.filter(
|
||||
(feature) =>
|
||||
feature.id !== featureId &&
|
||||
feature.type === "credit_system" &&
|
||||
feature.creditSchema?.some(
|
||||
(schema) => schema.meteredFeatureId === featureId,
|
||||
),
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { Customer } from "@useautumn/sdk";
|
||||
|
||||
type CustomerFeature = NonNullable<Customer["balances"][string]["feature"]>;
|
||||
|
||||
export const getCreditCost = ({
|
||||
featureId,
|
||||
creditSystem,
|
||||
amount = 1,
|
||||
}: {
|
||||
featureId: string;
|
||||
creditSystem: CustomerFeature;
|
||||
amount?: number;
|
||||
}) => {
|
||||
if (creditSystem.type !== "credit_system") {
|
||||
return amount;
|
||||
}
|
||||
|
||||
const schemaItem = creditSystem.creditSchema?.find(
|
||||
(schema) => schema.meteredFeatureId === featureId,
|
||||
);
|
||||
|
||||
return amount * (schemaItem?.creditCost ?? 1);
|
||||
};
|
||||
@@ -1,189 +0,0 @@
|
||||
import type { BalancesCheckResponse, Customer } from "@useautumn/sdk";
|
||||
import {
|
||||
type ApiBalanceInput,
|
||||
apiBalanceToAllowed,
|
||||
} from "../../../../../../shared/api/customers/cusFeatures/utils/convert/apiBalanceToAllowed";
|
||||
import type { ClientCheckParams } from "../../../types/params";
|
||||
import { toSnakeCase } from "../../../utils/toSnakeCase";
|
||||
|
||||
type CustomerBalance = Customer["balances"][string];
|
||||
|
||||
const resolveRequiredBalance = ({
|
||||
requiredBalance,
|
||||
requiredQuantity,
|
||||
}: {
|
||||
requiredBalance?: number;
|
||||
requiredQuantity?: number;
|
||||
}) => {
|
||||
return requiredBalance ?? requiredQuantity ?? 1;
|
||||
};
|
||||
|
||||
const isBalanceAllowed = ({
|
||||
balance,
|
||||
requiredBalance,
|
||||
}: {
|
||||
balance: CustomerBalance;
|
||||
requiredBalance: number;
|
||||
}) => {
|
||||
const snakeCaseBalance = toSnakeCase({
|
||||
obj: balance,
|
||||
}) as unknown as ApiBalanceInput;
|
||||
|
||||
const featureForCheck = {
|
||||
type: balance.feature?.type ?? "metered",
|
||||
} as Parameters<typeof apiBalanceToAllowed>[0]["feature"];
|
||||
|
||||
return apiBalanceToAllowed({
|
||||
apiBalance: snakeCaseBalance,
|
||||
feature: featureForCheck,
|
||||
requiredBalance,
|
||||
});
|
||||
};
|
||||
|
||||
const getCreditBalanceRequired = ({
|
||||
creditBalance,
|
||||
featureId,
|
||||
requiredBalance,
|
||||
}: {
|
||||
creditBalance: CustomerBalance;
|
||||
featureId: string;
|
||||
requiredBalance: number;
|
||||
}) => {
|
||||
const creditCost =
|
||||
creditBalance.feature?.creditSchema?.find(
|
||||
(schema) => schema.meteredFeatureId === featureId,
|
||||
)?.creditCost ?? 1;
|
||||
|
||||
return requiredBalance * creditCost;
|
||||
};
|
||||
|
||||
const getFeatureCheckResponse = ({
|
||||
customer,
|
||||
params,
|
||||
}: {
|
||||
customer: Customer;
|
||||
params: ClientCheckParams;
|
||||
}): BalancesCheckResponse => {
|
||||
const featureId = params.featureId;
|
||||
if (!featureId) {
|
||||
return {
|
||||
allowed: false,
|
||||
customerId: customer.id ?? "",
|
||||
entityId: params.entityId ?? null,
|
||||
requiredBalance: resolveRequiredBalance({
|
||||
requiredBalance: params.requiredBalance,
|
||||
requiredQuantity: params.requiredQuantity,
|
||||
}),
|
||||
balance: null,
|
||||
};
|
||||
}
|
||||
|
||||
const requiredBalance = resolveRequiredBalance({
|
||||
requiredBalance: params.requiredBalance,
|
||||
requiredQuantity: params.requiredQuantity,
|
||||
});
|
||||
|
||||
const mainBalance = customer.balances[featureId];
|
||||
|
||||
const creditBalances = Object.values(customer.balances).filter((balance) =>
|
||||
balance.feature?.creditSchema?.some(
|
||||
(schema) => schema.meteredFeatureId === featureId,
|
||||
),
|
||||
);
|
||||
|
||||
if (
|
||||
mainBalance &&
|
||||
isBalanceAllowed({ balance: mainBalance, requiredBalance })
|
||||
) {
|
||||
return {
|
||||
allowed: true,
|
||||
customerId: customer.id ?? "",
|
||||
entityId: params.entityId ?? null,
|
||||
requiredBalance,
|
||||
balance: mainBalance as BalancesCheckResponse["balance"],
|
||||
};
|
||||
}
|
||||
|
||||
for (const creditBalance of creditBalances) {
|
||||
const creditRequiredBalance = getCreditBalanceRequired({
|
||||
creditBalance,
|
||||
featureId,
|
||||
requiredBalance,
|
||||
});
|
||||
|
||||
if (
|
||||
isBalanceAllowed({
|
||||
balance: creditBalance,
|
||||
requiredBalance: creditRequiredBalance,
|
||||
})
|
||||
) {
|
||||
return {
|
||||
allowed: true,
|
||||
customerId: customer.id ?? "",
|
||||
entityId: params.entityId ?? null,
|
||||
requiredBalance: creditRequiredBalance,
|
||||
balance: creditBalance as BalancesCheckResponse["balance"],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (mainBalance) {
|
||||
return {
|
||||
allowed: false,
|
||||
customerId: customer.id ?? "",
|
||||
entityId: params.entityId ?? null,
|
||||
requiredBalance,
|
||||
balance: mainBalance as BalancesCheckResponse["balance"],
|
||||
};
|
||||
}
|
||||
|
||||
if (creditBalances.length > 0) {
|
||||
const firstCreditBalance = creditBalances[0];
|
||||
return {
|
||||
allowed: false,
|
||||
customerId: customer.id ?? "",
|
||||
entityId: params.entityId ?? null,
|
||||
requiredBalance: getCreditBalanceRequired({
|
||||
creditBalance: firstCreditBalance,
|
||||
featureId,
|
||||
requiredBalance,
|
||||
}),
|
||||
balance: firstCreditBalance as BalancesCheckResponse["balance"],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
allowed: false,
|
||||
customerId: customer.id ?? "",
|
||||
entityId: params.entityId ?? null,
|
||||
requiredBalance,
|
||||
balance: null,
|
||||
};
|
||||
};
|
||||
|
||||
export const getLocalCheckResponse = ({
|
||||
customer,
|
||||
params,
|
||||
}: {
|
||||
customer: Customer | null;
|
||||
params: ClientCheckParams;
|
||||
}): BalancesCheckResponse => {
|
||||
if (!customer) {
|
||||
return {
|
||||
allowed: false,
|
||||
customerId: "",
|
||||
entityId: params.entityId ?? null,
|
||||
requiredBalance: resolveRequiredBalance({
|
||||
requiredBalance: params.requiredBalance,
|
||||
requiredQuantity: params.requiredQuantity,
|
||||
}),
|
||||
balance: null,
|
||||
};
|
||||
}
|
||||
|
||||
if (!params.featureId) {
|
||||
throw new Error("check() requires featureId");
|
||||
}
|
||||
|
||||
return getFeatureCheckResponse({ customer, params });
|
||||
};
|
||||
@@ -0,0 +1,147 @@
|
||||
import type { BalancesCheckResponse, Customer } from "@useautumn/sdk";
|
||||
import type { ClientCheckParams } from "../../../types/params";
|
||||
import { balanceToAllowed } from "./check/balanceToAllowed";
|
||||
import { customerToFeatures } from "./check/customerToFeatures";
|
||||
import { findCreditSystemsByFeature } from "./check/findCreditSystemsByFeature";
|
||||
import { getCreditCost } from "./check/getCreditCost";
|
||||
|
||||
type CustomerBalance = Customer["balances"][string];
|
||||
type CustomerFeature = NonNullable<CustomerBalance["feature"]>;
|
||||
|
||||
const getFeatureToUse = ({
|
||||
featureId,
|
||||
features,
|
||||
feature,
|
||||
customer,
|
||||
requiredBalance,
|
||||
}: {
|
||||
featureId: string;
|
||||
features: CustomerFeature[];
|
||||
feature: CustomerFeature;
|
||||
customer: Customer;
|
||||
requiredBalance: number;
|
||||
}) => {
|
||||
const creditSystems = findCreditSystemsByFeature({
|
||||
featureId,
|
||||
features,
|
||||
});
|
||||
|
||||
if (creditSystems.length === 0) return feature;
|
||||
|
||||
const mainBalance = customer.balances[feature.id];
|
||||
if (
|
||||
mainBalance &&
|
||||
balanceToAllowed({
|
||||
balance: mainBalance,
|
||||
feature,
|
||||
requiredBalance,
|
||||
})
|
||||
) {
|
||||
return feature;
|
||||
}
|
||||
|
||||
for (const creditSystem of creditSystems) {
|
||||
const creditBalance = customer.balances[creditSystem.id];
|
||||
if (!creditBalance) continue;
|
||||
|
||||
const creditRequiredBalance = getCreditCost({
|
||||
featureId: feature.id,
|
||||
creditSystem,
|
||||
amount: requiredBalance,
|
||||
});
|
||||
|
||||
if (
|
||||
balanceToAllowed({
|
||||
balance: creditBalance,
|
||||
feature: creditSystem,
|
||||
requiredBalance: creditRequiredBalance,
|
||||
})
|
||||
) {
|
||||
return creditSystem;
|
||||
}
|
||||
}
|
||||
|
||||
return creditSystems[0];
|
||||
};
|
||||
|
||||
const getFeatureCheckResponse = ({
|
||||
customer,
|
||||
params,
|
||||
}: {
|
||||
customer: Customer;
|
||||
params: ClientCheckParams;
|
||||
}): BalancesCheckResponse => {
|
||||
const { featureId, requiredBalance = 1 } = params;
|
||||
|
||||
const features = customerToFeatures({ customer });
|
||||
const feature = features.find((item) => item.id === featureId);
|
||||
if (!feature) {
|
||||
throw new Error(`Feature ${featureId} not found`);
|
||||
}
|
||||
|
||||
const featureToUse = getFeatureToUse({
|
||||
featureId,
|
||||
features,
|
||||
feature,
|
||||
customer,
|
||||
requiredBalance,
|
||||
});
|
||||
|
||||
const balanceToUse = customer.balances[featureToUse.id];
|
||||
if (!balanceToUse) {
|
||||
return {
|
||||
allowed: false,
|
||||
customerId: customer.id ?? "",
|
||||
entityId: params.entityId ?? null,
|
||||
requiredBalance,
|
||||
balance: null,
|
||||
};
|
||||
}
|
||||
|
||||
const requiredBalanceToUse =
|
||||
featureToUse.type === "credit_system" && featureToUse.id !== feature.id
|
||||
? getCreditCost({
|
||||
featureId: feature.id,
|
||||
creditSystem: featureToUse,
|
||||
amount: requiredBalance,
|
||||
})
|
||||
: requiredBalance;
|
||||
|
||||
const allowed = balanceToAllowed({
|
||||
balance: balanceToUse,
|
||||
feature: featureToUse,
|
||||
requiredBalance: requiredBalanceToUse,
|
||||
});
|
||||
|
||||
return {
|
||||
allowed,
|
||||
customerId: customer.id ?? "",
|
||||
entityId: params.entityId ?? null,
|
||||
requiredBalance: requiredBalanceToUse,
|
||||
balance: balanceToUse as BalancesCheckResponse["balance"],
|
||||
};
|
||||
};
|
||||
|
||||
export const getLocalCheckResponse = ({
|
||||
customer,
|
||||
params,
|
||||
}: {
|
||||
customer: Customer | null;
|
||||
params: ClientCheckParams;
|
||||
}): BalancesCheckResponse => {
|
||||
if (!customer) {
|
||||
return {
|
||||
allowed: false,
|
||||
customerId: "",
|
||||
entityId: params.entityId ?? null,
|
||||
requiredBalance: params.requiredBalance ?? 1,
|
||||
balance: null,
|
||||
};
|
||||
}
|
||||
|
||||
if (!params.featureId) {
|
||||
throw new Error("check() requires featureId");
|
||||
}
|
||||
|
||||
return getFeatureCheckResponse({ customer, params });
|
||||
};
|
||||
@@ -8,7 +8,7 @@ import type {
|
||||
import { useCallback } from "react";
|
||||
import type { AttachParams, CheckParams } from "../../../types";
|
||||
import type { IAutumnClient } from "../../client/IAutumnClient";
|
||||
import { getLocalCheckResponse } from "./checkUtils";
|
||||
import { getLocalCheckResponse } from "./getLocalCheckResponse";
|
||||
|
||||
const redirectToUrl = ({
|
||||
url,
|
||||
|
||||
@@ -3910,6 +3910,7 @@ paths:
|
||||
description: ID which you provided when creating the customer
|
||||
feature_id:
|
||||
type: string
|
||||
description: ID of the feature to check access to.
|
||||
entity_id:
|
||||
type: string
|
||||
description: If using entity balances (eg, seats), the entity ID to check access
|
||||
@@ -3934,12 +3935,9 @@ paths:
|
||||
description: 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:
|
||||
type: string
|
||||
required_quantity:
|
||||
type: number
|
||||
required:
|
||||
- customer_id
|
||||
- feature_id
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
|
||||
@@ -3963,6 +3963,7 @@ paths:
|
||||
description: ID which you provided when creating the customer
|
||||
feature_id:
|
||||
type: string
|
||||
description: ID of the feature to check access to.
|
||||
entity_id:
|
||||
type: string
|
||||
description: If using entity balances (eg, seats), the entity ID to check access
|
||||
@@ -3987,12 +3988,9 @@ paths:
|
||||
description: 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:
|
||||
type: string
|
||||
required_quantity:
|
||||
type: number
|
||||
required:
|
||||
- customer_id
|
||||
- feature_id
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { SuccessResponseSchema } from "@api/common/commonResponses.js";
|
||||
import {
|
||||
CheckParamsSchema,
|
||||
CheckResponseV3Schema,
|
||||
CreateBalanceParamsV0Schema,
|
||||
ExtCheckParamsSchema,
|
||||
TrackParamsSchema,
|
||||
TrackResponseV3Schema,
|
||||
UpdateBalanceParamsSchema,
|
||||
@@ -51,7 +51,7 @@ export const balancesCheckContract = oc
|
||||
"x-speakeasy-name-override": "check",
|
||||
}),
|
||||
})
|
||||
.input(CheckParamsSchema)
|
||||
.input(ExtCheckParamsSchema)
|
||||
.output(CheckResponseV3Schema);
|
||||
|
||||
export const balancesTrackContract = oc
|
||||
|
||||
@@ -19,6 +19,7 @@ actions:
|
||||
async function run() {
|
||||
const result = await autumn.balances.check({
|
||||
customerId: "<id>",
|
||||
featureId: "<id>",
|
||||
});
|
||||
|
||||
console.log(result);
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
lockVersion: 2.0.0
|
||||
id: 7b300647-cd76-49e9-bf77-7d1bf5446d66
|
||||
management:
|
||||
docChecksum: 2599354f8d9fec10f95f15d1c9096b1d
|
||||
docChecksum: 41614313bae2edc9e0e3bbb7da66a4d6
|
||||
docVersion: 2.1.0
|
||||
speakeasyVersion: 1.719.0
|
||||
generationVersion: 2.824.1
|
||||
releaseVersion: 0.8.26
|
||||
configChecksum: b6c3c32777c82006d83440f8a980d2af
|
||||
releaseVersion: 0.8.27
|
||||
configChecksum: 58626b5f963b3bd6dae32861f7223e4e
|
||||
persistentEdits:
|
||||
generation_id: ddc35772-b2eb-4820-b753-62525d82a8eb
|
||||
pristine_commit_hash: 60a4122091e83ecafdd2621fef72c448d614bdf2
|
||||
pristine_tree_hash: eea50d885bff1b9f808c6350c2e0ad0b877155a9
|
||||
generation_id: e65473db-a4c6-4742-b95f-9b8012a90600
|
||||
pristine_commit_hash: 9070b0faec440397f5c71122d64b390fcff54c5f
|
||||
pristine_tree_hash: 2d507ad0bb4c7057b61076d8ab638fad99bd0e61
|
||||
features:
|
||||
typescript:
|
||||
additionalDependencies: 0.1.0
|
||||
@@ -144,8 +144,8 @@ trackedFiles:
|
||||
pristine_git_object: 654cee9ccd3ac3ab7e478e50d5bb8e6689078728
|
||||
docs/models/balances-check-request.md:
|
||||
id: 9bc2f38fe309
|
||||
last_write_checksum: sha1:84559e0a2c21e00b203b208b6e2c9f5b955652b0
|
||||
pristine_git_object: 83840a6bac824db113dd2484c4819b65edaf68b1
|
||||
last_write_checksum: sha1:0c05c1d4267bf87ccffbd12c2201ba77d3572b2e
|
||||
pristine_git_object: 3c287ef0a9fb8ba29a9747f85cd7f75fe9deacdb
|
||||
docs/models/balances-check-reset.md:
|
||||
id: 0bc9bade2bd6
|
||||
last_write_checksum: sha1:e62a7f8a2d10aba44af96cb2013ae8ef04bddbe7
|
||||
@@ -1480,8 +1480,8 @@ trackedFiles:
|
||||
pristine_git_object: 56e566eba7aeffa9422da7c6b4bcb80a123e5f14
|
||||
docs/sdks/balances/README.md:
|
||||
id: 6ca85866f00d
|
||||
last_write_checksum: sha1:a9d2e85ca386a826d73b0d402cde2afcc2bab0b5
|
||||
pristine_git_object: c7aa4176ebe0ecc174019273ac857b26e1986c2b
|
||||
last_write_checksum: sha1:eece4ef5879f579768573ba82c46936733b88b1f
|
||||
pristine_git_object: bf8790cb4364546e27a92b5705a0e7f25addeba1
|
||||
docs/sdks/billing/README.md:
|
||||
id: dc915331dd9d
|
||||
last_write_checksum: sha1:9e5ac33eb2f8161d4a9813184ce0bda310b5184e
|
||||
@@ -1516,12 +1516,12 @@ trackedFiles:
|
||||
pristine_git_object: 900d545ed58929951e2208e1bec791cb264429a4
|
||||
jsr.json:
|
||||
id: 7f6ab7767282
|
||||
last_write_checksum: sha1:81f59385b4f8527291ecad9b442981054bb1c9af
|
||||
pristine_git_object: 498da37844b72100f84a7a0e8dab8e6011222af1
|
||||
last_write_checksum: sha1:2f9caf84950826b0f80ea18b58f7a22fb1ff0b31
|
||||
pristine_git_object: 1d4fc089e365e8a54c922d38d6937921e6d63ba0
|
||||
package.json:
|
||||
id: 7030d0b2f71b
|
||||
last_write_checksum: sha1:1cf6dc171bd97df401d76a20b37cff97a8f79f2f
|
||||
pristine_git_object: ac3ec23ec56922ecd27496c75330ab80bb4ce2c4
|
||||
last_write_checksum: sha1:871236b8e1d9462e75ac2ba7a9e6654b2bc98a1d
|
||||
pristine_git_object: a99b0d11bd80af6de52463ca1d05ef57bb5a831f
|
||||
src/core.ts:
|
||||
id: f431fdbcd144
|
||||
last_write_checksum: sha1:f8f24a3ca09c1efb285d7a75ad3697d0128f47e2
|
||||
@@ -1604,8 +1604,8 @@ trackedFiles:
|
||||
pristine_git_object: 44be0eae8246521b230e8e711a88eff738fc015d
|
||||
src/lib/config.ts:
|
||||
id: 320761608fb3
|
||||
last_write_checksum: sha1:cbc217ef66dbc1a7713cea3ed30b3afbe58f85f8
|
||||
pristine_git_object: c80c88bd24b38e4183bb4602ef8df47e61d57381
|
||||
last_write_checksum: sha1:600c912298c99f0e576d6ced27c9f13619a6e693
|
||||
pristine_git_object: 7cb7a90dbda9a13ec9e20467e06cd2306df7146c
|
||||
src/lib/dlv.ts:
|
||||
id: b1988214835a
|
||||
last_write_checksum: sha1:1dd3e3fbb4550c4bf31f5ef997faff355d6f3250
|
||||
@@ -1672,8 +1672,8 @@ trackedFiles:
|
||||
pristine_git_object: 7cfcf2c90f1cfaa152ee2f4033187aa20b1c696b
|
||||
src/models/balances-check-op.ts:
|
||||
id: b818c72b5764
|
||||
last_write_checksum: sha1:43ba10dc6d3f77ac0c27566aa7da722be99b9b91
|
||||
pristine_git_object: 202ad5a71f0bfd85e6d100d8aa477d2c106f4e35
|
||||
last_write_checksum: sha1:ba49fee4c3f2246f0bb7ab82c4c737b64472e3d3
|
||||
pristine_git_object: 00b739d168f088a2a6660855f985f6889ea7069f
|
||||
src/models/balances-create-op.ts:
|
||||
id: 0ac1d9c85f60
|
||||
last_write_checksum: sha1:93f8b8a57403da4a95b83dcb2c7a54029694d2a4
|
||||
@@ -2258,7 +2258,7 @@ examples:
|
||||
header:
|
||||
x-api-version: "2.1"
|
||||
requestBody:
|
||||
application/json: {"customer_id": "<id>"}
|
||||
application/json: {"customer_id": "<id>", "feature_id": "<id>"}
|
||||
responses:
|
||||
"200":
|
||||
application/json: {"allowed": true, "customer_id": "<id>", "balance": {"feature_id": "<id>", "granted": 7002.31, "remaining": 9536.21, "usage": 3270.65, "unlimited": false, "overage_allowed": true, "max_purchase": 8252.55, "next_reset_at": 9394.31}}
|
||||
|
||||
@@ -33,7 +33,7 @@ generation:
|
||||
generateNewTests: true
|
||||
skipResponseBodyAssertions: false
|
||||
typescript:
|
||||
version: 0.8.26
|
||||
version: 0.8.27
|
||||
acceptHeaderEnum: false
|
||||
additionalDependencies:
|
||||
dependencies: {}
|
||||
|
||||
@@ -3922,6 +3922,7 @@ paths:
|
||||
description: ID which you provided when creating the customer
|
||||
feature_id:
|
||||
type: string
|
||||
description: ID of the feature to check access to.
|
||||
entity_id:
|
||||
type: string
|
||||
description: If using entity balances (eg, seats), the entity ID to check access for.
|
||||
@@ -3939,12 +3940,9 @@ paths:
|
||||
with_preview:
|
||||
type: boolean
|
||||
description: 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:
|
||||
type: string
|
||||
required_quantity:
|
||||
type: number
|
||||
required:
|
||||
- customer_id
|
||||
- feature_id
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
|
||||
@@ -9,8 +9,8 @@ sources:
|
||||
- 2.1.0
|
||||
Autumn API Stripped:
|
||||
sourceNamespace: autumn-api-stripped
|
||||
sourceRevisionDigest: sha256:3c2b0984859b57cb45257efef3e1a1bfe48fd0ef1c2e3c3702d42b955cf096db
|
||||
sourceBlobDigest: sha256:a10bc74dc833d54d6024f61f2d24fd5975f011ab69e88b489a46abb73c1eb4bd
|
||||
sourceRevisionDigest: sha256:40c850f3f37a4ef63ace5e1bdfad2671d0f524de9cb7505fc9bd1cd61d90fbb6
|
||||
sourceBlobDigest: sha256:d2a2be089c9d86271ff50f9910f11306fb30e365c419b0c255f9fba2a675cdc7
|
||||
tags:
|
||||
- latest
|
||||
- 2.1.0
|
||||
@@ -25,10 +25,10 @@ targets:
|
||||
autumn-python:
|
||||
source: Autumn API Stripped
|
||||
sourceNamespace: autumn-api-stripped
|
||||
sourceRevisionDigest: sha256:3c2b0984859b57cb45257efef3e1a1bfe48fd0ef1c2e3c3702d42b955cf096db
|
||||
sourceBlobDigest: sha256:a10bc74dc833d54d6024f61f2d24fd5975f011ab69e88b489a46abb73c1eb4bd
|
||||
sourceRevisionDigest: sha256:40c850f3f37a4ef63ace5e1bdfad2671d0f524de9cb7505fc9bd1cd61d90fbb6
|
||||
sourceBlobDigest: sha256:d2a2be089c9d86271ff50f9910f11306fb30e365c419b0c255f9fba2a675cdc7
|
||||
codeSamplesNamespace: autumn-api-python-code-samples
|
||||
codeSamplesRevisionDigest: sha256:ca39ee64d522fc8fdba083d3fc8eef936be15f8f65340bb75bb6cce7b7190561
|
||||
codeSamplesRevisionDigest: sha256:3cd6e4413b7a3d4adb59b7ae7c943dc291d6a2f8cf6416ddb8b286d1a56c9a47
|
||||
workflow:
|
||||
workflowVersion: 1.0.0
|
||||
speakeasyVersion: pinned
|
||||
|
||||
@@ -7,6 +7,7 @@ import { BalancesCheckRequest } from "@useautumn/sdk";
|
||||
|
||||
let value: BalancesCheckRequest = {
|
||||
customerId: "<id>",
|
||||
featureId: "<id>",
|
||||
};
|
||||
```
|
||||
|
||||
@@ -15,11 +16,9 @@ let value: BalancesCheckRequest = {
|
||||
| Field | Type | Required | Description |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `customerId` | *string* | :heavy_check_mark: | ID which you provided when creating the customer |
|
||||
| `featureId` | *string* | :heavy_minus_sign: | N/A |
|
||||
| `featureId` | *string* | :heavy_check_mark: | ID of the feature to check access to. |
|
||||
| `entityId` | *string* | :heavy_minus_sign: | If using entity balances (eg, seats), the entity ID to check access for. |
|
||||
| `requiredBalance` | *number* | :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` | Record<string, *any*> | :heavy_minus_sign: | N/A |
|
||||
| `sendEvent` | *boolean* | :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. |
|
||||
| `withPreview` | *boolean* | :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. |
|
||||
| `productId` | *string* | :heavy_minus_sign: | N/A |
|
||||
| `requiredQuantity` | *number* | :heavy_minus_sign: | N/A |
|
||||
| `withPreview` | *boolean* | :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. |
|
||||
@@ -181,6 +181,7 @@ const autumn = new Autumn({
|
||||
async function run() {
|
||||
const result = await autumn.balances.check({
|
||||
customerId: "<id>",
|
||||
featureId: "<id>",
|
||||
});
|
||||
|
||||
console.log(result);
|
||||
@@ -207,6 +208,7 @@ const autumn = new AutumnCore({
|
||||
async function run() {
|
||||
const res = await balancesCheck(autumn, {
|
||||
customerId: "<id>",
|
||||
featureId: "<id>",
|
||||
});
|
||||
if (res.ok) {
|
||||
const { value: result } = res;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{
|
||||
"name": "@useautumn/sdk",
|
||||
"version": "0.8.26",
|
||||
"version": "0.8.27",
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./models": "./src/models/index.ts",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@useautumn/sdk",
|
||||
"version": "0.8.26",
|
||||
"version": "0.8.27",
|
||||
"author": "Speakeasy",
|
||||
"main": "./dist/commonjs/index.js",
|
||||
"module": "./dist/esm/index.js",
|
||||
|
||||
@@ -66,7 +66,7 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
|
||||
export const SDK_METADATA = {
|
||||
language: "typescript",
|
||||
openapiDocVersion: "2.1.0",
|
||||
sdkVersion: "0.8.26",
|
||||
sdkVersion: "0.8.27",
|
||||
genVersion: "2.824.1",
|
||||
userAgent: "speakeasy-sdk/typescript 0.8.26 2.824.1 2.1.0 @useautumn/sdk",
|
||||
userAgent: "speakeasy-sdk/typescript 0.8.27 2.824.1 2.1.0 @useautumn/sdk",
|
||||
} as const;
|
||||
|
||||
@@ -21,7 +21,10 @@ export type BalancesCheckRequest = {
|
||||
* ID which you provided when creating the customer
|
||||
*/
|
||||
customerId: string;
|
||||
featureId?: string | undefined;
|
||||
/**
|
||||
* ID of the feature to check access to.
|
||||
*/
|
||||
featureId: string;
|
||||
/**
|
||||
* If using entity balances (eg, seats), the entity ID to check access for.
|
||||
*/
|
||||
@@ -39,8 +42,6 @@ export type BalancesCheckRequest = {
|
||||
* If true, the response will include a preview object, which can be used to display information such as a paywall or upgrade confirmation.
|
||||
*/
|
||||
withPreview?: boolean | undefined;
|
||||
productId?: string | undefined;
|
||||
requiredQuantity?: number | undefined;
|
||||
};
|
||||
|
||||
export const BalancesCheckBalanceType = {
|
||||
@@ -490,14 +491,12 @@ export type BalancesCheckResponse = {
|
||||
/** @internal */
|
||||
export type BalancesCheckRequest$Outbound = {
|
||||
customer_id: string;
|
||||
feature_id?: string | undefined;
|
||||
feature_id: string;
|
||||
entity_id?: string | undefined;
|
||||
required_balance?: number | undefined;
|
||||
properties?: { [k: string]: any } | undefined;
|
||||
send_event?: boolean | undefined;
|
||||
with_preview?: boolean | undefined;
|
||||
product_id?: string | undefined;
|
||||
required_quantity?: number | undefined;
|
||||
};
|
||||
|
||||
/** @internal */
|
||||
@@ -507,14 +506,12 @@ export const BalancesCheckRequest$outboundSchema: z.ZodMiniType<
|
||||
> = z.pipe(
|
||||
z.object({
|
||||
customerId: z.string(),
|
||||
featureId: z.optional(z.string()),
|
||||
featureId: z.string(),
|
||||
entityId: z.optional(z.string()),
|
||||
requiredBalance: z.optional(z.number()),
|
||||
properties: z.optional(z.record(z.string(), z.any())),
|
||||
sendEvent: z.optional(z.boolean()),
|
||||
withPreview: z.optional(z.boolean()),
|
||||
productId: z.optional(z.string()),
|
||||
requiredQuantity: z.optional(z.number()),
|
||||
}),
|
||||
z.transform((v) => {
|
||||
return remap$(v, {
|
||||
@@ -524,8 +521,6 @@ export const BalancesCheckRequest$outboundSchema: z.ZodMiniType<
|
||||
requiredBalance: "required_balance",
|
||||
sendEvent: "send_event",
|
||||
withPreview: "with_preview",
|
||||
productId: "product_id",
|
||||
requiredQuantity: "required_quantity",
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ApiFeatureType } from "@api/features/prevVersions/apiFeatureV0";
|
||||
import type { EntInterval } from "@models/productModels/intervals/entitlementInterval";
|
||||
import { resetIntvToEntIntv } from "@utils/productV2Utils/productItemUtils/convertProductItem/planItemIntervals";
|
||||
import { Decimal } from "decimal";
|
||||
import { Decimal } from "decimal.js";
|
||||
import type { z } from "zod/v4";
|
||||
import { FeatureType } from "../../../../models/featureModels/featureEnums";
|
||||
import { sumValues } from "../../../../utils/utils";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { deduplicateArray } from "@utils/utils";
|
||||
import { Decimal } from "decimal";
|
||||
import { Decimal } from "decimal.js";
|
||||
import type { ApiBalance, ApiBalanceBreakdown } from "../apiBalance";
|
||||
import type { ApiBalanceBreakdownV1, ApiBalanceV1 } from "../apiBalanceV1";
|
||||
import { apiBalanceV1ToPrepaidQuantity } from "../utils/convert/apiBalanceV1ToPrepaidQuantity";
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
import {
|
||||
type ApiBalanceInput,
|
||||
type ApiCustomerV5,
|
||||
type ApiEntityV2,
|
||||
apiBalanceToAllowed,
|
||||
type FeatureInput,
|
||||
} from "../convert/apiBalanceToAllowed";
|
||||
|
||||
type CheckFeatureInput = FeatureInput & {
|
||||
id: string;
|
||||
};
|
||||
|
||||
type CheckEntityInput = {
|
||||
balances?: Record<string, ApiBalanceInput | undefined>;
|
||||
};
|
||||
type Feature,
|
||||
} from "../../../../../index";
|
||||
|
||||
export const getFeatureToUseForCheck = ({
|
||||
creditSystems,
|
||||
@@ -18,9 +11,9 @@ export const getFeatureToUseForCheck = ({
|
||||
apiEntity,
|
||||
requiredBalance,
|
||||
}: {
|
||||
creditSystems: CheckFeatureInput[];
|
||||
feature: CheckFeatureInput;
|
||||
apiEntity: CheckEntityInput;
|
||||
creditSystems: Feature[];
|
||||
feature: Feature;
|
||||
apiEntity: ApiCustomerV5 | ApiEntityV2;
|
||||
requiredBalance: number;
|
||||
}) => {
|
||||
// 1. If there's a credit system & cusEnts for that credit system -> return credit system
|
||||
|
||||
@@ -1,36 +1,16 @@
|
||||
import type { ApiBalanceV1 } from "@api/customers/cusFeatures/apiBalanceV1";
|
||||
import { apiBalanceV1ToAvailableOverage } from "@api/customers/cusFeatures/utils/convert/apiBalanceV1ToAvailableOverage";
|
||||
import type { Feature } from "@models/featureModels/featureModels";
|
||||
import { isBooleanFeature, notNullish } from "@utils/index";
|
||||
import { Decimal } from "decimal.js";
|
||||
import { apiBalanceV1ToAvailableOverage } from "./apiBalanceV1ToAvailableOverage";
|
||||
|
||||
export type ApiBalanceBreakdownInput = {
|
||||
usage: number;
|
||||
included_grant: number;
|
||||
prepaid_grant: number;
|
||||
price?: {
|
||||
billing_method?: string;
|
||||
max_purchase: number | null;
|
||||
} | null;
|
||||
overage?: number;
|
||||
};
|
||||
|
||||
export type ApiBalanceInput = {
|
||||
unlimited: boolean;
|
||||
overage_allowed: boolean;
|
||||
remaining: number;
|
||||
max_purchase: number | null;
|
||||
breakdown?: ApiBalanceBreakdownInput[];
|
||||
};
|
||||
|
||||
export type FeatureInput = {
|
||||
type?: string;
|
||||
};
|
||||
|
||||
export const apiBalanceToAllowed = ({
|
||||
apiBalance,
|
||||
feature,
|
||||
requiredBalance,
|
||||
}: {
|
||||
apiBalance: ApiBalanceInput;
|
||||
feature: FeatureInput;
|
||||
apiBalance: ApiBalanceV1;
|
||||
feature: Feature;
|
||||
requiredBalance: number;
|
||||
}) => {
|
||||
if (!apiBalance) {
|
||||
@@ -38,7 +18,7 @@ export const apiBalanceToAllowed = ({
|
||||
}
|
||||
|
||||
// 1. Boolean
|
||||
if (feature.type === "boolean") {
|
||||
if (isBooleanFeature({ feature })) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -57,7 +37,7 @@ export const apiBalanceToAllowed = ({
|
||||
// 1. Available overage
|
||||
const availableOverage = apiBalanceV1ToAvailableOverage({ apiBalance });
|
||||
|
||||
if (availableOverage !== null && availableOverage !== undefined) {
|
||||
if (notNullish(availableOverage)) {
|
||||
return new Decimal(availableOverage)
|
||||
.add(apiBalance.remaining)
|
||||
.gte(requiredBalance);
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
import { sumValues } from "@utils/utils";
|
||||
import { Decimal } from "decimal.js";
|
||||
import type {
|
||||
ApiBalanceBreakdownInput,
|
||||
ApiBalanceInput,
|
||||
} from "./apiBalanceToAllowed";
|
||||
import type { ApiBalanceBreakdownV1, ApiBalanceV1 } from "../../apiBalanceV1";
|
||||
import { apiBalanceV1ToOverage } from "./apiBalanceV1ToOverage";
|
||||
|
||||
const sumValues = (values: number[]) =>
|
||||
values.reduce((total, value) => total + value, 0);
|
||||
|
||||
export const apiBalanceBreakdownV1ToMaxOverage = ({
|
||||
apiBalanceBreakdown,
|
||||
}: {
|
||||
apiBalanceBreakdown: ApiBalanceBreakdownInput;
|
||||
apiBalanceBreakdown: ApiBalanceBreakdownV1;
|
||||
}): number | undefined => {
|
||||
if (apiBalanceBreakdown.price?.billing_method === "usage_based") {
|
||||
return apiBalanceBreakdown.price?.max_purchase ?? undefined;
|
||||
@@ -23,7 +18,7 @@ export const apiBalanceBreakdownV1ToMaxOverage = ({
|
||||
export const apiBalanceV1ToMaxOverage = ({
|
||||
apiBalance,
|
||||
}: {
|
||||
apiBalance: ApiBalanceInput;
|
||||
apiBalance: ApiBalanceV1;
|
||||
}): number | undefined => {
|
||||
const breakdownItems = apiBalance.breakdown ?? [];
|
||||
|
||||
@@ -43,7 +38,7 @@ export const apiBalanceV1ToMaxOverage = ({
|
||||
export const apiBalanceV1ToAvailableOverage = ({
|
||||
apiBalance,
|
||||
}: {
|
||||
apiBalance: ApiBalanceInput;
|
||||
apiBalance: ApiBalanceV1;
|
||||
}): number | undefined => {
|
||||
const maxOverage = apiBalanceV1ToMaxOverage({ apiBalance });
|
||||
const overage = apiBalanceV1ToOverage({ apiBalance });
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
import type {
|
||||
ApiBalanceBreakdownInput,
|
||||
ApiBalanceInput,
|
||||
} from "./apiBalanceToAllowed";
|
||||
|
||||
const sumValues = (values: number[]) =>
|
||||
values.reduce((total, value) => total + value, 0);
|
||||
import { sumValues } from "@utils/utils";
|
||||
import type { ApiBalanceBreakdownV1, ApiBalanceV1 } from "../../apiBalanceV1";
|
||||
|
||||
export const apiBalanceBreakdownV1ToOverage = ({
|
||||
apiBalanceBreakdown,
|
||||
}: {
|
||||
apiBalanceBreakdown: ApiBalanceBreakdownInput;
|
||||
apiBalanceBreakdown: ApiBalanceBreakdownV1;
|
||||
}) => {
|
||||
// const overage = Math.max(
|
||||
// 0,
|
||||
@@ -25,7 +20,7 @@ export const apiBalanceBreakdownV1ToOverage = ({
|
||||
export const apiBalanceV1ToOverage = ({
|
||||
apiBalance,
|
||||
}: {
|
||||
apiBalance: ApiBalanceInput;
|
||||
apiBalance: ApiBalanceV1;
|
||||
}) => {
|
||||
const breakdownItems = apiBalance.breakdown ?? [];
|
||||
|
||||
|
||||
@@ -1,41 +1,22 @@
|
||||
type ApiCustomerFeatureInput = {
|
||||
id: string;
|
||||
name?: string;
|
||||
type?: string;
|
||||
credit_schema?: Array<{
|
||||
metered_feature_id: string;
|
||||
credit_cost: number;
|
||||
}>;
|
||||
creditSchema?: Array<{
|
||||
meteredFeatureId: string;
|
||||
creditCost: number;
|
||||
}>;
|
||||
};
|
||||
|
||||
type ApiCustomerBalanceInput = {
|
||||
feature?: ApiCustomerFeatureInput;
|
||||
};
|
||||
|
||||
export type ApiCustomerWithBalancesInput = {
|
||||
balances: Record<string, ApiCustomerBalanceInput>;
|
||||
};
|
||||
import type { ApiFeatureV1 } from "../../features/apiFeatureV1";
|
||||
import type { ApiCustomerV5 } from "../apiCustomerV5";
|
||||
|
||||
export const apiCustomerToFeatures = ({
|
||||
apiCustomer,
|
||||
}: {
|
||||
apiCustomer: ApiCustomerWithBalancesInput;
|
||||
}) => {
|
||||
apiCustomer: ApiCustomerV5;
|
||||
}): ApiFeatureV1[] => {
|
||||
const balances = Object.values(apiCustomer.balances);
|
||||
if (balances.length === 0) return [];
|
||||
|
||||
const firstBalance = balances[0];
|
||||
if (!firstBalance.feature) {
|
||||
throw new Error(
|
||||
"[customerToFeatures] please expand `balances.feature` to get features for the customer",
|
||||
"[apiCustomerToFeatures] please expand `balances.feature` to get features for the customer",
|
||||
);
|
||||
}
|
||||
|
||||
return Object.values(apiCustomer.balances).map((balance) => {
|
||||
return balance.feature;
|
||||
}) as ApiCustomerFeatureInput[]; // safe to cast because we checked for feature in the first balance
|
||||
return Object.values(apiCustomer.balances)
|
||||
.map((balance) => balance.feature)
|
||||
.filter((feature): feature is ApiFeatureV1 => feature !== undefined);
|
||||
};
|
||||
|
||||
@@ -1 +1 @@
|
||||
export * from "./apiCustomerToFeatures";
|
||||
export * from "./apiCustomerToFeatures.js";
|
||||
|
||||
Reference in New Issue
Block a user