Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: one more tweak to the PlanStorage interface #1280

Merged
merged 2 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions packages/capabilities/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ export type CARLink = Link<unknown, typeof CAR.codec.code>
export type AccountDID = DID<'mailto'>
export type SpaceDID = DID<'key'>

/**
* Error for cases where an interface implementation needs to return an
* error that isn't defined explicitly in the interface.
*/
export interface UnexpectedError extends Ucanto.Failure {
name: 'UnexpectedError'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name: 'UnexpectedError'
name: 'UnexpectedError'
cause: unknown

I would make a slot for the caught error whatever it may be.

}

/**
* failure due to a resource not having enough storage capacity.
*/
Expand Down Expand Up @@ -628,7 +636,7 @@ export interface PlanNotFound extends Ucanto.Failure {
name: 'PlanNotFound'
}

export type PlanGetFailure = PlanNotFound
export type PlanGetFailure = PlanNotFound | UnexpectedError

export type PlanSet = InferInvokedCapability<typeof PlanCaps.set>

Expand All @@ -645,7 +653,14 @@ export interface InvalidPlanName extends Ucanto.Failure {
name: 'InvalidPlanName'
}

export type PlanSetFailure = CustomerNotFound
export interface PlanUpdateError extends Ucanto.Failure {
name: 'PlanUpdateError'
}

export type PlanSetFailure =
| CustomerNotFound
| PlanUpdateError
| UnexpectedError

// Top
export type Top = InferInvokedCapability<typeof top>
Expand Down
7 changes: 7 additions & 0 deletions packages/upload-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
"customer": [
"dist/src/customer.d.ts"
],
"plan": [
"dist/src/plan.d.ts"
],
"provider": [
"dist/src/provider.d.ts"
],
Expand Down Expand Up @@ -81,6 +84,10 @@
"types": "./dist/src/provider.d.ts",
"import": "./src/provider.js"
},
"./plan": {
"types": "./dist/src/plan.d.ts",
"import": "./src/plan.js"
},
"./space": {
"types": "./dist/src/space.d.ts",
"import": "./src/space.js"
Expand Down
16 changes: 12 additions & 4 deletions packages/upload-api/src/types/plans.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import * as Ucanto from '@ucanto/interface'
import { AccountDID, DID, PlanGetFailure, PlanGetSuccess, PlanSetFailure, PlanSetSuccess } from '../types.js'
import {
AccountDID,
DID,
PlanGetFailure,
PlanGetSuccess,
PlanSetFailure,
PlanSetSuccess,
UnexpectedError,
} from '../types.js'

export type PlanID = DID

export interface CustomerExists extends Ucanto.Failure {
name: 'CustomerExists'
}

type PlanInitializeFailure = CustomerExists
type PlanInitializeFailure = CustomerExists | UnexpectedError

/**
* Stores subscription plan information.
Expand All @@ -16,10 +24,10 @@ export interface PlansStorage {
/**
* Initialize a customer in our system, tracking the external billing
* system ID and the plan they have chosen.
*
*
* Designed to be use from, eg, a webhook handler for an account creation event
* in a third party billing system.
*
*
* @param account account DID
* @param billingID ID used by billing system to track this account
* @param plan the ID of the initial plan
Expand Down
22 changes: 18 additions & 4 deletions packages/upload-api/test/storage/plans-storage-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,22 @@ export const test = {
'can initialize a customer': async (assert, context) => {
const storage = context.plansStorage

const initializeResult = await storage.initialize(account, billingID, product)
const initializeResult = await storage.initialize(
account,
billingID,
product
)

assert.ok(initializeResult.ok)

const getResult = await storage.get(account)
assert.equal(getResult.ok?.product, product)
},

'should not allow plans to be updated for uninitialized customers': async (assert, context) => {
'should not allow plans to be updated for uninitialized customers': async (
assert,
context
) => {
const storage = context.plansStorage

const setResult = await storage.set(account, product)
Expand All @@ -28,10 +35,17 @@ export const test = {
assert.equal(setResult.error?.name, 'CustomerNotFound')
},

'should allow plans to be updated for initialized customers': async (assert, context) => {
'should allow plans to be updated for initialized customers': async (
assert,
context
) => {
const storage = context.plansStorage

const initializeResult = await storage.initialize(account, billingID, product)
const initializeResult = await storage.initialize(
account,
billingID,
product
)

assert.ok(initializeResult.ok)

Expand Down
14 changes: 9 additions & 5 deletions packages/upload-api/test/storage/plans-storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,20 @@ export class PlansStorage {
}

/**
*
* @param {Types.AccountDID} account
* @param {string} billingID
* @param {Types.DID} product
*
* @param {Types.AccountDID} account
* @param {string} billingID
* @param {Types.DID} product
*/
async initialize(account, billingID, product) {
if (this.plans[account]) {
return { error: new CustomerExists(account) }
}
this.plans[account] = { product, billingID, updatedAt: new Date().toISOString() }
this.plans[account] = {
product,
billingID,
updatedAt: new Date().toISOString(),
}
return { ok: {} }
}

Expand Down
Loading