import type { Failure, ServiceMethod, UCANLink, HandlerExecutionError, Signer, DID, DIDKey, InboundCodec, Result, CapabilityParser, Match, ParsedCapability, InferInvokedCapability, RevocationChecker, ToString, UnknownLink, Unit, } from '@ucanto/interface' import type { ProviderInput, ConnectionView } from '@ucanto/server' import { Signer as EdSigner } from '@ucanto/principal/ed25519' import { StorefrontService } from '@web3-storage/filecoin-api/types' import { ServiceContext as FilecoinServiceContext } from '@web3-storage/filecoin-api/storefront/api' import { DelegationsStorage as Delegations } from './types/delegations.js' import { ProvisionsStorage as Provisions } from './types/provisions.js' import { RateLimitsStorage as RateLimits } from './types/rate-limits.js' import { UsageStorage } from './types/usage.js' export type ValidationEmailSend = { to: string url: string } export type SpaceDID = DIDKey export type ServiceDID = DID<'web'> export type ServiceSigner = Signer export interface SpaceProviderRegistry { hasStorageProvider(space: SpaceDID): Promise> } export interface InsufficientStorage extends Failure { name: 'InsufficientStorage' } export type AllocationError = InsufficientStorage export interface Email { sendValidation: (input: { to: string; url: string }) => Promise } export interface DebugEmail extends Email { emails: Array take: () => Promise } import { StoreAdd, StoreGet, StoreAddSuccess, StoreRemove, StoreRemoveSuccess, StoreRemoveFailure, StoreList, StoreListSuccess, StoreListItem, UploadAdd, UploadGet, UploadAddSuccess, UploadRemove, UploadRemoveSuccess, UploadList, UploadListSuccess, UploadListItem, AccessAuthorize, AccessAuthorizeSuccess, AccessDelegate, AccessDelegateFailure, AccessDelegateSuccess, AccessClaim, AccessClaimSuccess, AccessClaimFailure, AccessConfirm, AccessConfirmSuccess, AccessConfirmFailure, ConsumerHas, ConsumerHasSuccess, ConsumerHasFailure, ConsumerGet, ConsumerGetSuccess, ConsumerGetFailure, CustomerGet, CustomerGetSuccess, CustomerGetFailure, SubscriptionGet, SubscriptionGetSuccess, SubscriptionGetFailure, SubscriptionList, SubscriptionListSuccess, SubscriptionListFailure, RateLimitAdd, RateLimitAddSuccess, RateLimitAddFailure, RateLimitRemove, RateLimitRemoveSuccess, RateLimitRemoveFailure, RateLimitList, RateLimitListSuccess, RateLimitListFailure, AdminStoreInspect, AdminStoreInspectSuccess, AdminStoreInspectFailure, AdminUploadInspect, AdminUploadInspectSuccess, AdminUploadInspectFailure, ProviderAdd, ProviderAddSuccess, ProviderAddFailure, SpaceInfo, ProviderDID, StoreGetFailure, UploadGetFailure, ListResponse, CARLink, StoreGetSuccess, UploadGetSuccess, UCANRevoke, UCANRevokeSuccess, UCANRevokeFailure, PlanGet, PlanGetSuccess, PlanGetFailure, AccessAuthorizeFailure, UsageReportSuccess, UsageReportFailure, UsageReport, } from '@web3-storage/capabilities/types' import * as Capabilities from '@web3-storage/capabilities' import { RevocationsStorage } from './types/revocations.js' export * from '@web3-storage/capabilities/types' export * from '@ucanto/interface' export type { ProvisionsStorage, Provision } from './types/provisions.js' export type { DelegationsStorage, Query as DelegationsStorageQuery, } from './types/delegations.js' export type { Revocation, RevocationQuery, MatchingRevocations, RevocationsStorage, } from './types/revocations.js' export type { RateLimitsStorage, RateLimit } from './types/rate-limits.js' import { PlansStorage } from './types/plans.js' export type { PlansStorage } from './types/plans.js' import { SubscriptionsStorage } from './types/subscriptions.js' export type { SubscriptionsStorage } export interface Service extends StorefrontService { store: { add: ServiceMethod get: ServiceMethod remove: ServiceMethod list: ServiceMethod } upload: { add: ServiceMethod get: ServiceMethod remove: ServiceMethod list: ServiceMethod } console: { log: ServiceMethod< InferInvokedCapability, Unit, never > error: ServiceMethod< InferInvokedCapability, never, Failure & { cause: unknown } > } access: { authorize: ServiceMethod< AccessAuthorize, AccessAuthorizeSuccess, AccessAuthorizeFailure > claim: ServiceMethod confirm: ServiceMethod< AccessConfirm, AccessConfirmSuccess, AccessConfirmFailure > delegate: ServiceMethod< AccessDelegate, AccessDelegateSuccess, AccessDelegateFailure > } consumer: { has: ServiceMethod get: ServiceMethod } customer: { get: ServiceMethod } subscription: { get: ServiceMethod< SubscriptionGet, SubscriptionGetSuccess, SubscriptionGetFailure > list: ServiceMethod< SubscriptionList, SubscriptionListSuccess, SubscriptionListFailure > } 'rate-limit': { add: ServiceMethod remove: ServiceMethod< RateLimitRemove, RateLimitRemoveSuccess, RateLimitRemoveFailure > list: ServiceMethod< RateLimitList, RateLimitListSuccess, RateLimitListFailure > } ucan: { revoke: ServiceMethod } admin: { store: { inspect: ServiceMethod< AdminStoreInspect, AdminStoreInspectSuccess, AdminStoreInspectFailure > } upload: { inspect: ServiceMethod< AdminUploadInspect, AdminUploadInspectSuccess, AdminUploadInspectFailure > } } provider: { add: ServiceMethod } space: { info: ServiceMethod } plan: { get: ServiceMethod } usage: { report: ServiceMethod } } export type StoreServiceContext = SpaceServiceContext & { maxUploadSize: number storeTable: StoreTable carStoreBucket: CarStoreBucket } export type UploadServiceContext = ConsumerServiceContext & SpaceServiceContext & RevocationServiceContext & { signer: EdSigner.Signer uploadTable: UploadTable dudewhereBucket: DudewhereBucket } export interface AccessClaimContext { delegationsStorage: Delegations } export type AccessServiceContext = AccessClaimContext & { signer: EdSigner.Signer email: Email url: URL provisionsStorage: Provisions rateLimitsStorage: RateLimits } export interface ConsumerServiceContext { signer: EdSigner.Signer provisionsStorage: Provisions } export interface CustomerServiceContext { signer: EdSigner.Signer provisionsStorage: Provisions } export interface AdminServiceContext { signer: EdSigner.Signer uploadTable: UploadTable storeTable: StoreTable } export interface ConsoleServiceContext {} export interface SpaceServiceContext { provisionsStorage: Provisions delegationsStorage: Delegations rateLimitsStorage: RateLimits } export interface ProviderServiceContext { provisionsStorage: Provisions rateLimitsStorage: RateLimits plansStorage: PlansStorage requirePaymentPlan?: boolean } export interface SubscriptionServiceContext { signer: EdSigner.Signer provisionsStorage: Provisions subscriptionsStorage: SubscriptionsStorage } export interface RateLimitServiceContext { rateLimitsStorage: RateLimits } export interface RevocationServiceContext { revocationsStorage: RevocationsStorage } export interface PlanServiceContext { plansStorage: PlansStorage } export interface UsageServiceContext { provisionsStorage: Provisions usageStorage: UsageStorage } export interface ServiceContext extends AccessServiceContext, ConsoleServiceContext, ConsumerServiceContext, CustomerServiceContext, ProviderServiceContext, SpaceServiceContext, StoreServiceContext, SubscriptionServiceContext, RateLimitServiceContext, RevocationServiceContext, PlanServiceContext, UploadServiceContext, FilecoinServiceContext, UsageServiceContext {} export interface UcantoServerContext extends ServiceContext, RevocationChecker { id: Signer codec?: InboundCodec errorReporter: ErrorReporter } export interface UcantoServerTestContext extends UcantoServerContext, StoreTestContext, UploadTestContext { connection: ConnectionView mail: DebugEmail service: Signer fetch: typeof fetch grantAccess: (mail: { url: string | URL }) => Promise } export interface StoreTestContext {} export interface UploadTestContext {} export interface ErrorReporter { catch: (error: HandlerExecutionError) => void } export interface CarStoreBucket { has: (link: UnknownLink) => Promise createUploadUrl: ( link: UnknownLink, size: number ) => Promise<{ url: URL headers: { 'x-amz-checksum-sha256': string 'content-length': string } & Record }> } export interface CarStoreBucketOptions { accessKeyId?: string secretAccessKey?: string region?: string bucket?: string sessionToken?: string expires?: number } export interface CarStoreBucketService { use(options?: CarStoreBucketOptions): Promise } export interface DudewhereBucket { put: (dataCid: string, carCid: string) => Promise } export interface StoreTable { inspect: (link: UnknownLink) => Promise exists: (space: DID, link: UnknownLink) => Promise get: (space: DID, link: UnknownLink) => Promise insert: (item: StoreAddInput) => Promise remove: (space: DID, link: UnknownLink) => Promise list: ( space: DID, options?: ListOptions ) => Promise> } export interface UploadTable { inspect: (link: UnknownLink) => Promise exists: (space: DID, root: UnknownLink) => Promise get: (space: DID, link: UnknownLink) => Promise insert: (item: UploadAddInput) => Promise remove: (space: DID, root: UnknownLink) => Promise list: ( space: DID, options?: ListOptions ) => Promise> } export type SpaceInfoSuccess = { did: SpaceDID providers: ProviderDID[] } export type SpaceInfoFailure = Failure | SpaceUnknown export interface UnknownProvider extends Failure { name: 'UnknownProvider' } export type CustomerGetResult = Result export type SubscriptionGetResult = Result< SubscriptionGetSuccess, SubscriptionGetFailure > export type AdminStoreInspectResult = Result< AdminStoreInspectSuccess, AdminStoreInspectFailure > export type AdminUploadInspectResult = Result< AdminUploadInspectSuccess, AdminUploadInspectFailure > export interface StoreAddInput { space: DID link: UnknownLink size: number origin?: UnknownLink issuer: DID invocation: UCANLink } export interface StoreAddOutput extends Omit {} export interface StoreInspectSuccess { spaces: Array<{ did: DID; insertedAt: string }> } export interface UploadAddInput { space: DID root: UnknownLink shards?: CARLink[] issuer: DID invocation: UCANLink } export interface UploadInspectSuccess { spaces: Array<{ did: DID; insertedAt: string }> } export interface ListOptions { size?: number cursor?: string pre?: boolean } export interface TestSpaceRegistry { /** * Registers space with the registry. */ registerSpace: (space: DID) => Promise } export interface LinkJSON { '/': ToString } export interface SpaceUnknown extends Failure { name: 'SpaceUnknown' } export type Input>> = ProviderInput & ParsedCapability> export interface Assert { equal: ( actual: Actual, expected: Expected, message?: string ) => unknown deepEqual: ( actual: Actual, expected: Expected, message?: string ) => unknown ok: (actual: Actual, message?: string) => unknown } export type Test = (assert: Assert, context: UcantoServerTestContext) => unknown export type Tests = Record