Improved XRPC error protocol (#194)
* Add lexicon doc * Update error-handling spec * Implement new error-behaviors in xrpc and xrpc-server packages * Update lexicon and lex-cli packages to add xrpc error behaviors * Generate new API and test an error behavior
This commit is contained in:
parent
31bd54e69c
commit
a21417ba91
docs/specs
packages
api/src
index.tsschemas.ts
types/todo
lex-cli/src/codegen
lexicon/src
server
src
api/todo/adx
lexicon
schemas.ts
types/todo
tests
xrpc-server
xrpc/src
schemas/todo.adx
@ -133,44 +133,7 @@ To fetch a schema, a request must be sent to the xrpc [`getSchema`](../xrpc.md#g
|
||||
|
||||
### Schema structure
|
||||
|
||||
Record schemas are encoded in JSON and adhere to the following interface:
|
||||
|
||||
```typescript
|
||||
interface RecordSchema {
|
||||
adx: 1
|
||||
id: string
|
||||
revision?: number // a versioning counter
|
||||
description?: string
|
||||
record: JSONSchema
|
||||
}
|
||||
```
|
||||
|
||||
Here is an example schema:
|
||||
|
||||
```json
|
||||
{
|
||||
"adx": 1,
|
||||
"id": "com.example.post",
|
||||
"record": {
|
||||
"type": "object",
|
||||
"required": ["text", "createdAt"],
|
||||
"properties": {
|
||||
"text": {"type": "string", "maxLength": 256},
|
||||
"createdAt": {"type": "string", "format": "date-time"}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And here is a record using this example schema:
|
||||
|
||||
```json
|
||||
{
|
||||
"$type": "com.example.post",
|
||||
"text": "Hello, world!",
|
||||
"createdAt": "2022-09-15T16:37:17.131Z"
|
||||
}
|
||||
```
|
||||
Record schemas are encoded in JSON using [Lexicon Schema Documents](../lexicon.md).
|
||||
|
||||
### Reserved field names
|
||||
|
||||
|
111
docs/specs/lexicon.md
Normal file
111
docs/specs/lexicon.md
Normal file
@ -0,0 +1,111 @@
|
||||
# Lexicon Schema Documents
|
||||
|
||||
Lexicon is a schemas document format used to define [XRPC](./xrpc.md) methods and [ATP Repository](./adx/repo.md) record types. Every Lexicon schema is written in JSON and follows the interface specified below. The schemas are identified using [NSIDs](./nsid.md) which are then used to identify the methods or record types they describe.
|
||||
|
||||
## Interface
|
||||
|
||||
```typescript
|
||||
interface LexiconDoc {
|
||||
lexicon: 1
|
||||
id: string // an NSID
|
||||
type: 'query' | 'procedure' | 'record'
|
||||
revision?: number
|
||||
description?: string
|
||||
}
|
||||
|
||||
interface RecordLexiconDoc extends LexiconDoc {
|
||||
record: JSONSchema
|
||||
}
|
||||
|
||||
interface XrpcLexiconDoc extends LexiconDoc {
|
||||
parameters?: Record<string, XrpcParameter>
|
||||
input?: XrpcBody
|
||||
output?: XrpcBody
|
||||
errors?: XrpcError[]
|
||||
}
|
||||
|
||||
interface XrpcParameter {
|
||||
type: 'string' | 'number' | 'integer' | 'boolean'
|
||||
description?: string
|
||||
default?: string | number | boolean
|
||||
required?: boolean
|
||||
minLength?: number
|
||||
maxLength?: number
|
||||
minimum?: number
|
||||
maximum?: number
|
||||
}
|
||||
|
||||
interface XrpcBody {
|
||||
encoding: string|string[]
|
||||
schema: JSONSchema
|
||||
}
|
||||
|
||||
interface XrpcError {
|
||||
name: string
|
||||
description?: string
|
||||
}
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### XRPC Method
|
||||
|
||||
```json
|
||||
{
|
||||
"lexicon": 1,
|
||||
"id": "todo.adx.createAccount",
|
||||
"type": "procedure",
|
||||
"description": "Create an account.",
|
||||
"parameters": {},
|
||||
"input": {
|
||||
"encoding": "application/json",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": ["email", "username", "password"],
|
||||
"properties": {
|
||||
"email": {"type": "string"},
|
||||
"username": {"type": "string"},
|
||||
"inviteCode": {"type": "string"},
|
||||
"password": {"type": "string"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"encoding": "application/json",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": ["jwt", "name", "did"],
|
||||
"properties": {
|
||||
"jwt": { "type": "string" },
|
||||
"name": {"type": "string"},
|
||||
"did": {"type": "string"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"errors": [
|
||||
{"name": "InvalidEmail"},
|
||||
{"name": "InvalidUsername"},
|
||||
{"name": "InvalidPassword"},
|
||||
{"name": "InvalidInviteCode"},
|
||||
{"name": "UsernameTaken"},
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### ATP Record Type
|
||||
|
||||
```json
|
||||
{
|
||||
"lexicon": 1,
|
||||
"id": "todo.social.repost",
|
||||
"type": "record",
|
||||
"record": {
|
||||
"type": "object",
|
||||
"required": ["subject", "createdAt"],
|
||||
"properties": {
|
||||
"subject": {"type": "string"},
|
||||
"createdAt": {"type": "string", "format": "date-time"}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
@ -73,82 +73,7 @@ net.users.bob.ping
|
||||
|
||||
#### Method schemas
|
||||
|
||||
Method schemas are encoded in JSON and adhere to the following interface:
|
||||
|
||||
```typescript
|
||||
interface MethodSchema {
|
||||
xrpc: 1
|
||||
id: string
|
||||
type: 'query' | 'procedure'
|
||||
description?: string
|
||||
parameters?: Record<string, MethodParam> // a map of param names to their definitions
|
||||
input?: MethodBody
|
||||
output?: MethodBody
|
||||
}
|
||||
|
||||
interface MethodParam {
|
||||
type: 'string' | 'number' | 'integer' | 'boolean'
|
||||
description?: string
|
||||
default?: string | number | boolean
|
||||
required?: boolean
|
||||
minLength?: number // string only
|
||||
maxLength?: number // string only
|
||||
minimum?: number // number and integer only
|
||||
maximum?: number // number and integer only
|
||||
}
|
||||
|
||||
interface MethodBody {
|
||||
encoding: string | string[] // must be a valid mimetype
|
||||
schema?: JSONSchema // json only
|
||||
}
|
||||
```
|
||||
|
||||
An example query-method schema:
|
||||
|
||||
```json
|
||||
{
|
||||
"xrpc": 1,
|
||||
"id": "io.social.getFeed",
|
||||
"type": "query",
|
||||
"description": "Fetch the user's latest feed.",
|
||||
"parameters": {
|
||||
"limit": {"type": "integer", "minimum": 1, "maximum": 50},
|
||||
"cursor": {"type": "string"},
|
||||
"reverse": {"type": "boolean", "default": true}
|
||||
},
|
||||
"output": {
|
||||
"encoding": "application/json",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": ["entries", "totalCount"],
|
||||
"properties": {
|
||||
"entries": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Entry items will vary and are not constrained at the method level"
|
||||
}
|
||||
},
|
||||
"totalCount": {"type": "number"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
An example procedure-method schema:
|
||||
|
||||
```json
|
||||
{
|
||||
"xrpc": 1,
|
||||
"id": "io.social.setProfilePicture",
|
||||
"type": "procedure",
|
||||
"description": "Set the user's avatar.",
|
||||
"input": {
|
||||
"encoding": ["image/png", "image/jpg"],
|
||||
}
|
||||
}
|
||||
```
|
||||
Method schemas are encoded in JSON using [Lexicon Schema Documents](./lexicon.md).
|
||||
|
||||
#### Schema distribution
|
||||
|
||||
@ -211,10 +136,7 @@ The request has succeeded. Expectations:
|
||||
|
||||
#### `400` Invalid request
|
||||
|
||||
The request is invalid and was not processed. Expecations:
|
||||
|
||||
- `Content-Type` header must be `application/json`.
|
||||
- Response body must match the [InvalidRequest](#invalidrequest) schema.
|
||||
The request is invalid and was not processed.
|
||||
|
||||
#### `401` Authentication required
|
||||
|
||||
@ -244,10 +166,7 @@ The client has sent too many requests. Rate-limits are decided by each server. E
|
||||
|
||||
#### `500` Internal server error
|
||||
|
||||
The server reached an unexpected condition during processing. Expecations:
|
||||
|
||||
- `Content-Type` header must be `application/json`.
|
||||
- Response body must match the [InternalError](#internalerror) schema.
|
||||
The server reached an unexpected condition during processing.
|
||||
|
||||
#### `501` Method not implemented
|
||||
|
||||
@ -255,10 +174,7 @@ The server does not implement the requested method.
|
||||
|
||||
#### `502` A request to upstream failed
|
||||
|
||||
The execution of the procedure depends on a call to another server which has failed. Expecations:
|
||||
|
||||
- `Content-Type` header must be `application/json`.
|
||||
- Response body must match the [UpstreamError](#upstreamerror) schema.
|
||||
The execution of the procedure depends on a call to another server which has failed.
|
||||
|
||||
#### `503` Not enough resources
|
||||
|
||||
@ -266,10 +182,7 @@ The server is under heavy load and can't complete the request.
|
||||
|
||||
#### `504` A request to upstream timed out
|
||||
|
||||
The execution of the procedure depends on a call to another server which timed out. Expecations:
|
||||
|
||||
- `Content-Type` header must be `application/json`.
|
||||
- Response body must match the [UpstreamError](#upstreamerror) schema.
|
||||
The execution of the procedure depends on a call to another server which timed out.
|
||||
|
||||
#### Remaining codes
|
||||
|
||||
@ -285,36 +198,15 @@ Any response code not explicitly enumerated should be handled as follows:
|
||||
|
||||
TODO
|
||||
|
||||
### Response schemas
|
||||
### Custom error codes and descriptions
|
||||
|
||||
The following schemas are used within the XRPC protocol.
|
||||
|
||||
#### `InvalidRequest`
|
||||
In non-200 (error) responses, services may respond with a JSON body which matches the following schema:
|
||||
|
||||
```typescript
|
||||
interface InvalidRequest {
|
||||
error: true
|
||||
type: 'InvalidRequest'
|
||||
message: string
|
||||
interface XrpcErrorDescription {
|
||||
error?: string
|
||||
message?: string
|
||||
}
|
||||
```
|
||||
|
||||
#### `InternalError`
|
||||
|
||||
```typescript
|
||||
interface InternalError {
|
||||
error: true
|
||||
type: 'InternalError'
|
||||
message: string
|
||||
}
|
||||
```
|
||||
|
||||
#### `UpstreamError`
|
||||
|
||||
```typescript
|
||||
interface UpstreamError {
|
||||
error: true
|
||||
type: 'UpstreamError'
|
||||
message: string
|
||||
}
|
||||
```
|
||||
The `error` field of the response body should map to an error name defined in the method's [Lexicon schema](./lexicon.md). This enables more specific error-handling by client software. This is especially advised on 400, 500, and 502 responses where further information will be useful.
|
@ -40,6 +40,40 @@ import * as TodoSocialPost from './types/todo/social/post'
|
||||
import * as TodoSocialProfile from './types/todo/social/profile'
|
||||
import * as TodoSocialRepost from './types/todo/social/repost'
|
||||
|
||||
export * as TodoAdxCreateAccount from './types/todo/adx/createAccount'
|
||||
export * as TodoAdxCreateSession from './types/todo/adx/createSession'
|
||||
export * as TodoAdxDeleteAccount from './types/todo/adx/deleteAccount'
|
||||
export * as TodoAdxDeleteSession from './types/todo/adx/deleteSession'
|
||||
export * as TodoAdxGetAccount from './types/todo/adx/getAccount'
|
||||
export * as TodoAdxGetAccountsConfig from './types/todo/adx/getAccountsConfig'
|
||||
export * as TodoAdxGetSession from './types/todo/adx/getSession'
|
||||
export * as TodoAdxRepoBatchWrite from './types/todo/adx/repoBatchWrite'
|
||||
export * as TodoAdxRepoCreateRecord from './types/todo/adx/repoCreateRecord'
|
||||
export * as TodoAdxRepoDeleteRecord from './types/todo/adx/repoDeleteRecord'
|
||||
export * as TodoAdxRepoDescribe from './types/todo/adx/repoDescribe'
|
||||
export * as TodoAdxRepoGetRecord from './types/todo/adx/repoGetRecord'
|
||||
export * as TodoAdxRepoListRecords from './types/todo/adx/repoListRecords'
|
||||
export * as TodoAdxRepoPutRecord from './types/todo/adx/repoPutRecord'
|
||||
export * as TodoAdxResolveName from './types/todo/adx/resolveName'
|
||||
export * as TodoAdxSyncGetRepo from './types/todo/adx/syncGetRepo'
|
||||
export * as TodoAdxSyncGetRoot from './types/todo/adx/syncGetRoot'
|
||||
export * as TodoAdxSyncUpdateRepo from './types/todo/adx/syncUpdateRepo'
|
||||
export * as TodoSocialBadge from './types/todo/social/badge'
|
||||
export * as TodoSocialFollow from './types/todo/social/follow'
|
||||
export * as TodoSocialGetFeed from './types/todo/social/getFeed'
|
||||
export * as TodoSocialGetLikedBy from './types/todo/social/getLikedBy'
|
||||
export * as TodoSocialGetNotifications from './types/todo/social/getNotifications'
|
||||
export * as TodoSocialGetPostThread from './types/todo/social/getPostThread'
|
||||
export * as TodoSocialGetProfile from './types/todo/social/getProfile'
|
||||
export * as TodoSocialGetRepostedBy from './types/todo/social/getRepostedBy'
|
||||
export * as TodoSocialGetUserFollowers from './types/todo/social/getUserFollowers'
|
||||
export * as TodoSocialGetUserFollows from './types/todo/social/getUserFollows'
|
||||
export * as TodoSocialLike from './types/todo/social/like'
|
||||
export * as TodoSocialMediaEmbed from './types/todo/social/mediaEmbed'
|
||||
export * as TodoSocialPost from './types/todo/social/post'
|
||||
export * as TodoSocialProfile from './types/todo/social/profile'
|
||||
export * as TodoSocialRepost from './types/todo/social/repost'
|
||||
|
||||
export class Client {
|
||||
xrpc: XrpcClient = new XrpcClient()
|
||||
|
||||
@ -95,7 +129,11 @@ export class AdxNS {
|
||||
data?: TodoAdxCreateAccount.InputSchema,
|
||||
opts?: TodoAdxCreateAccount.CallOptions
|
||||
): Promise<TodoAdxCreateAccount.Response> {
|
||||
return this._service.xrpc.call('todo.adx.createAccount', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.createAccount', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxCreateAccount.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
createSession(
|
||||
@ -103,7 +141,11 @@ export class AdxNS {
|
||||
data?: TodoAdxCreateSession.InputSchema,
|
||||
opts?: TodoAdxCreateSession.CallOptions
|
||||
): Promise<TodoAdxCreateSession.Response> {
|
||||
return this._service.xrpc.call('todo.adx.createSession', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.createSession', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxCreateSession.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
deleteAccount(
|
||||
@ -111,7 +153,11 @@ export class AdxNS {
|
||||
data?: TodoAdxDeleteAccount.InputSchema,
|
||||
opts?: TodoAdxDeleteAccount.CallOptions
|
||||
): Promise<TodoAdxDeleteAccount.Response> {
|
||||
return this._service.xrpc.call('todo.adx.deleteAccount', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.deleteAccount', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxDeleteAccount.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
deleteSession(
|
||||
@ -119,7 +165,11 @@ export class AdxNS {
|
||||
data?: TodoAdxDeleteSession.InputSchema,
|
||||
opts?: TodoAdxDeleteSession.CallOptions
|
||||
): Promise<TodoAdxDeleteSession.Response> {
|
||||
return this._service.xrpc.call('todo.adx.deleteSession', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.deleteSession', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxDeleteSession.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
getAccount(
|
||||
@ -127,7 +177,11 @@ export class AdxNS {
|
||||
data?: TodoAdxGetAccount.InputSchema,
|
||||
opts?: TodoAdxGetAccount.CallOptions
|
||||
): Promise<TodoAdxGetAccount.Response> {
|
||||
return this._service.xrpc.call('todo.adx.getAccount', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.getAccount', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxGetAccount.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
getAccountsConfig(
|
||||
@ -135,12 +189,11 @@ export class AdxNS {
|
||||
data?: TodoAdxGetAccountsConfig.InputSchema,
|
||||
opts?: TodoAdxGetAccountsConfig.CallOptions
|
||||
): Promise<TodoAdxGetAccountsConfig.Response> {
|
||||
return this._service.xrpc.call(
|
||||
'todo.adx.getAccountsConfig',
|
||||
params,
|
||||
data,
|
||||
opts
|
||||
)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.getAccountsConfig', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxGetAccountsConfig.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
getSession(
|
||||
@ -148,7 +201,11 @@ export class AdxNS {
|
||||
data?: TodoAdxGetSession.InputSchema,
|
||||
opts?: TodoAdxGetSession.CallOptions
|
||||
): Promise<TodoAdxGetSession.Response> {
|
||||
return this._service.xrpc.call('todo.adx.getSession', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.getSession', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxGetSession.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
repoBatchWrite(
|
||||
@ -156,12 +213,11 @@ export class AdxNS {
|
||||
data?: TodoAdxRepoBatchWrite.InputSchema,
|
||||
opts?: TodoAdxRepoBatchWrite.CallOptions
|
||||
): Promise<TodoAdxRepoBatchWrite.Response> {
|
||||
return this._service.xrpc.call(
|
||||
'todo.adx.repoBatchWrite',
|
||||
params,
|
||||
data,
|
||||
opts
|
||||
)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.repoBatchWrite', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxRepoBatchWrite.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
repoCreateRecord(
|
||||
@ -169,12 +225,11 @@ export class AdxNS {
|
||||
data?: TodoAdxRepoCreateRecord.InputSchema,
|
||||
opts?: TodoAdxRepoCreateRecord.CallOptions
|
||||
): Promise<TodoAdxRepoCreateRecord.Response> {
|
||||
return this._service.xrpc.call(
|
||||
'todo.adx.repoCreateRecord',
|
||||
params,
|
||||
data,
|
||||
opts
|
||||
)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.repoCreateRecord', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxRepoCreateRecord.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
repoDeleteRecord(
|
||||
@ -182,12 +237,11 @@ export class AdxNS {
|
||||
data?: TodoAdxRepoDeleteRecord.InputSchema,
|
||||
opts?: TodoAdxRepoDeleteRecord.CallOptions
|
||||
): Promise<TodoAdxRepoDeleteRecord.Response> {
|
||||
return this._service.xrpc.call(
|
||||
'todo.adx.repoDeleteRecord',
|
||||
params,
|
||||
data,
|
||||
opts
|
||||
)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.repoDeleteRecord', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxRepoDeleteRecord.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
repoDescribe(
|
||||
@ -195,7 +249,11 @@ export class AdxNS {
|
||||
data?: TodoAdxRepoDescribe.InputSchema,
|
||||
opts?: TodoAdxRepoDescribe.CallOptions
|
||||
): Promise<TodoAdxRepoDescribe.Response> {
|
||||
return this._service.xrpc.call('todo.adx.repoDescribe', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.repoDescribe', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxRepoDescribe.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
repoGetRecord(
|
||||
@ -203,7 +261,11 @@ export class AdxNS {
|
||||
data?: TodoAdxRepoGetRecord.InputSchema,
|
||||
opts?: TodoAdxRepoGetRecord.CallOptions
|
||||
): Promise<TodoAdxRepoGetRecord.Response> {
|
||||
return this._service.xrpc.call('todo.adx.repoGetRecord', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.repoGetRecord', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxRepoGetRecord.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
repoListRecords(
|
||||
@ -211,12 +273,11 @@ export class AdxNS {
|
||||
data?: TodoAdxRepoListRecords.InputSchema,
|
||||
opts?: TodoAdxRepoListRecords.CallOptions
|
||||
): Promise<TodoAdxRepoListRecords.Response> {
|
||||
return this._service.xrpc.call(
|
||||
'todo.adx.repoListRecords',
|
||||
params,
|
||||
data,
|
||||
opts
|
||||
)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.repoListRecords', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxRepoListRecords.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
repoPutRecord(
|
||||
@ -224,7 +285,11 @@ export class AdxNS {
|
||||
data?: TodoAdxRepoPutRecord.InputSchema,
|
||||
opts?: TodoAdxRepoPutRecord.CallOptions
|
||||
): Promise<TodoAdxRepoPutRecord.Response> {
|
||||
return this._service.xrpc.call('todo.adx.repoPutRecord', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.repoPutRecord', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxRepoPutRecord.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
resolveName(
|
||||
@ -232,7 +297,11 @@ export class AdxNS {
|
||||
data?: TodoAdxResolveName.InputSchema,
|
||||
opts?: TodoAdxResolveName.CallOptions
|
||||
): Promise<TodoAdxResolveName.Response> {
|
||||
return this._service.xrpc.call('todo.adx.resolveName', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.resolveName', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxResolveName.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
syncGetRepo(
|
||||
@ -240,7 +309,11 @@ export class AdxNS {
|
||||
data?: TodoAdxSyncGetRepo.InputSchema,
|
||||
opts?: TodoAdxSyncGetRepo.CallOptions
|
||||
): Promise<TodoAdxSyncGetRepo.Response> {
|
||||
return this._service.xrpc.call('todo.adx.syncGetRepo', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.syncGetRepo', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxSyncGetRepo.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
syncGetRoot(
|
||||
@ -248,7 +321,11 @@ export class AdxNS {
|
||||
data?: TodoAdxSyncGetRoot.InputSchema,
|
||||
opts?: TodoAdxSyncGetRoot.CallOptions
|
||||
): Promise<TodoAdxSyncGetRoot.Response> {
|
||||
return this._service.xrpc.call('todo.adx.syncGetRoot', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.syncGetRoot', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxSyncGetRoot.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
syncUpdateRepo(
|
||||
@ -256,12 +333,11 @@ export class AdxNS {
|
||||
data?: TodoAdxSyncUpdateRepo.InputSchema,
|
||||
opts?: TodoAdxSyncUpdateRepo.CallOptions
|
||||
): Promise<TodoAdxSyncUpdateRepo.Response> {
|
||||
return this._service.xrpc.call(
|
||||
'todo.adx.syncUpdateRepo',
|
||||
params,
|
||||
data,
|
||||
opts
|
||||
)
|
||||
return this._service.xrpc
|
||||
.call('todo.adx.syncUpdateRepo', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoAdxSyncUpdateRepo.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,7 +367,11 @@ export class SocialNS {
|
||||
data?: TodoSocialGetFeed.InputSchema,
|
||||
opts?: TodoSocialGetFeed.CallOptions
|
||||
): Promise<TodoSocialGetFeed.Response> {
|
||||
return this._service.xrpc.call('todo.social.getFeed', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.social.getFeed', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoSocialGetFeed.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
getLikedBy(
|
||||
@ -299,7 +379,11 @@ export class SocialNS {
|
||||
data?: TodoSocialGetLikedBy.InputSchema,
|
||||
opts?: TodoSocialGetLikedBy.CallOptions
|
||||
): Promise<TodoSocialGetLikedBy.Response> {
|
||||
return this._service.xrpc.call('todo.social.getLikedBy', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.social.getLikedBy', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoSocialGetLikedBy.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
getNotifications(
|
||||
@ -307,12 +391,11 @@ export class SocialNS {
|
||||
data?: TodoSocialGetNotifications.InputSchema,
|
||||
opts?: TodoSocialGetNotifications.CallOptions
|
||||
): Promise<TodoSocialGetNotifications.Response> {
|
||||
return this._service.xrpc.call(
|
||||
'todo.social.getNotifications',
|
||||
params,
|
||||
data,
|
||||
opts
|
||||
)
|
||||
return this._service.xrpc
|
||||
.call('todo.social.getNotifications', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoSocialGetNotifications.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
getPostThread(
|
||||
@ -320,12 +403,11 @@ export class SocialNS {
|
||||
data?: TodoSocialGetPostThread.InputSchema,
|
||||
opts?: TodoSocialGetPostThread.CallOptions
|
||||
): Promise<TodoSocialGetPostThread.Response> {
|
||||
return this._service.xrpc.call(
|
||||
'todo.social.getPostThread',
|
||||
params,
|
||||
data,
|
||||
opts
|
||||
)
|
||||
return this._service.xrpc
|
||||
.call('todo.social.getPostThread', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoSocialGetPostThread.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
getProfile(
|
||||
@ -333,7 +415,11 @@ export class SocialNS {
|
||||
data?: TodoSocialGetProfile.InputSchema,
|
||||
opts?: TodoSocialGetProfile.CallOptions
|
||||
): Promise<TodoSocialGetProfile.Response> {
|
||||
return this._service.xrpc.call('todo.social.getProfile', params, data, opts)
|
||||
return this._service.xrpc
|
||||
.call('todo.social.getProfile', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoSocialGetProfile.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
getRepostedBy(
|
||||
@ -341,12 +427,11 @@ export class SocialNS {
|
||||
data?: TodoSocialGetRepostedBy.InputSchema,
|
||||
opts?: TodoSocialGetRepostedBy.CallOptions
|
||||
): Promise<TodoSocialGetRepostedBy.Response> {
|
||||
return this._service.xrpc.call(
|
||||
'todo.social.getRepostedBy',
|
||||
params,
|
||||
data,
|
||||
opts
|
||||
)
|
||||
return this._service.xrpc
|
||||
.call('todo.social.getRepostedBy', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoSocialGetRepostedBy.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
getUserFollowers(
|
||||
@ -354,12 +439,11 @@ export class SocialNS {
|
||||
data?: TodoSocialGetUserFollowers.InputSchema,
|
||||
opts?: TodoSocialGetUserFollowers.CallOptions
|
||||
): Promise<TodoSocialGetUserFollowers.Response> {
|
||||
return this._service.xrpc.call(
|
||||
'todo.social.getUserFollowers',
|
||||
params,
|
||||
data,
|
||||
opts
|
||||
)
|
||||
return this._service.xrpc
|
||||
.call('todo.social.getUserFollowers', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoSocialGetUserFollowers.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
|
||||
getUserFollows(
|
||||
@ -367,12 +451,11 @@ export class SocialNS {
|
||||
data?: TodoSocialGetUserFollows.InputSchema,
|
||||
opts?: TodoSocialGetUserFollows.CallOptions
|
||||
): Promise<TodoSocialGetUserFollows.Response> {
|
||||
return this._service.xrpc.call(
|
||||
'todo.social.getUserFollows',
|
||||
params,
|
||||
data,
|
||||
opts
|
||||
)
|
||||
return this._service.xrpc
|
||||
.call('todo.social.getUserFollows', params, data, opts)
|
||||
.catch((e) => {
|
||||
throw TodoSocialGetUserFollows.toKnownErr(e)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,17 @@ export const methodSchemas: MethodSchema[] = [
|
||||
},
|
||||
},
|
||||
},
|
||||
errors: [
|
||||
{
|
||||
name: 'InvalidUsername',
|
||||
},
|
||||
{
|
||||
name: 'InvalidPassword',
|
||||
},
|
||||
{
|
||||
name: 'UsernameNotAvailable',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
lexicon: 1,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {}
|
||||
|
||||
@ -22,7 +22,34 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export class InvalidUsernameError extends XRPCError {
|
||||
constructor(src: XRPCError) {
|
||||
super(src.status, src.error, src.message)
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidPasswordError extends XRPCError {
|
||||
constructor(src: XRPCError) {
|
||||
super(src.status, src.error, src.message)
|
||||
}
|
||||
}
|
||||
|
||||
export class UsernameNotAvailableError extends XRPCError {
|
||||
constructor(src: XRPCError) {
|
||||
super(src.status, src.error, src.message)
|
||||
}
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
if (e.error === 'InvalidUsername') return new InvalidUsernameError(e)
|
||||
if (e.error === 'InvalidPassword') return new InvalidPasswordError(e)
|
||||
if (e.error === 'UsernameNotAvailable')
|
||||
return new UsernameNotAvailableError(e)
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {}
|
||||
|
||||
@ -23,7 +23,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {}
|
||||
|
||||
@ -20,7 +20,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {}
|
||||
|
||||
@ -20,7 +20,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {}
|
||||
|
||||
@ -20,7 +20,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {}
|
||||
|
||||
@ -18,7 +18,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {}
|
||||
|
||||
@ -18,7 +18,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
did: string;
|
||||
@ -40,7 +40,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
did: string;
|
||||
@ -24,7 +24,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
did: string;
|
||||
@ -17,6 +17,11 @@ export type InputSchema = undefined
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
nameOrDid: string;
|
||||
@ -23,7 +23,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
nameOrDid: string;
|
||||
@ -22,7 +22,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
nameOrDid: string;
|
||||
@ -27,7 +27,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
did: string;
|
||||
@ -25,7 +25,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
name?: string;
|
||||
@ -19,7 +19,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
did: string;
|
||||
@ -16,7 +16,12 @@ export type InputSchema = undefined
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: Uint8Array;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
did: string;
|
||||
@ -19,7 +19,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
did: string;
|
||||
@ -16,6 +16,11 @@ export type InputSchema = string | Uint8Array
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
author?: string;
|
||||
@ -56,7 +56,12 @@ export interface UnknownEmbed {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
uri: string;
|
||||
@ -28,7 +28,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
limit?: number;
|
||||
@ -31,7 +31,12 @@ export interface Notification {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
uri: string;
|
||||
@ -56,7 +56,12 @@ export interface UnknownEmbed {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
user: string;
|
||||
@ -42,7 +42,12 @@ export interface Badge {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
uri: string;
|
||||
@ -28,7 +28,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
user: string;
|
||||
@ -32,7 +32,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* GENERATED CODE - DO NOT MODIFY
|
||||
*/
|
||||
import { Headers } from '@adxp/xrpc'
|
||||
import { Headers, XRPCError } from '@adxp/xrpc'
|
||||
|
||||
export interface QueryParams {
|
||||
user: string;
|
||||
@ -32,7 +32,12 @@ export interface OutputSchema {
|
||||
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
error: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
|
||||
export function toKnownErr(e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -53,13 +53,15 @@ const indexTs = (project: Project, schemas: Schema[], nsidTree: NsidNS[]) =>
|
||||
.addImportDeclaration({ moduleSpecifier: './schemas' })
|
||||
.addNamedImports([{ name: 'methodSchemas' }, { name: 'recordSchemas' }])
|
||||
|
||||
// generate type imports
|
||||
// generate type imports and re-exports
|
||||
for (const schema of schemas) {
|
||||
const moduleSpecifier = `./types/${schema.id.split('.').join('/')}`
|
||||
file
|
||||
.addImportDeclaration({
|
||||
moduleSpecifier: `./types/${schema.id.split('.').join('/')}`,
|
||||
})
|
||||
.addImportDeclaration({ moduleSpecifier })
|
||||
.setNamespaceImport(toTitleCase(schema.id))
|
||||
file
|
||||
.addExportDeclaration({ moduleSpecifier })
|
||||
.setNamespaceExport(toTitleCase(schema.id))
|
||||
}
|
||||
|
||||
//= export class Client {...}
|
||||
@ -255,7 +257,13 @@ function genNamespaceCls(file: SourceFile, ns: NsidNS) {
|
||||
type: `${moduleName}.CallOptions`,
|
||||
})
|
||||
method.setBodyText(
|
||||
`return this._service.xrpc.call('${schema.id}', params, data, opts)`,
|
||||
[
|
||||
`return this._service.xrpc`,
|
||||
` .call('${schema.id}', params, data, opts)`,
|
||||
` .catch((e) => {`,
|
||||
` throw ${moduleName}.toKnownErr(e)`,
|
||||
` })`,
|
||||
].join('\n'),
|
||||
)
|
||||
}
|
||||
|
||||
@ -409,13 +417,11 @@ function genRecordCls(file: SourceFile, schema: RecordSchema) {
|
||||
|
||||
const methodSchemaTs = (project, schema: MethodSchema) =>
|
||||
gen(project, `/types/${schema.id.split('.').join('/')}.ts`, async (file) => {
|
||||
//= import {Headers} from '@adxp/xrpc'
|
||||
//= import {Headers, XRPCError} from '@adxp/xrpc'
|
||||
const xrpcImport = file.addImportDeclaration({
|
||||
moduleSpecifier: '@adxp/xrpc',
|
||||
})
|
||||
xrpcImport.addNamedImport({
|
||||
name: 'Headers',
|
||||
})
|
||||
xrpcImport.addNamedImports([{ name: 'Headers' }, { name: 'XRPCError' }])
|
||||
|
||||
//= export interface QueryParams {...}
|
||||
const qp = file.addInterface({
|
||||
@ -493,7 +499,6 @@ const methodSchemaTs = (project, schema: MethodSchema) =>
|
||||
isExported: true,
|
||||
})
|
||||
res.addProperty({ name: 'success', type: 'boolean' })
|
||||
res.addProperty({ name: 'error', type: 'boolean' })
|
||||
res.addProperty({ name: 'headers', type: 'Headers' })
|
||||
if (schema.output?.schema) {
|
||||
if (Array.isArray(schema.output.encoding)) {
|
||||
@ -504,6 +509,41 @@ const methodSchemaTs = (project, schema: MethodSchema) =>
|
||||
} else if (schema.output?.encoding) {
|
||||
res.addProperty({ name: 'data', type: 'Uint8Array' })
|
||||
}
|
||||
|
||||
// export class {errcode}Error {...}
|
||||
const customErrors: { name: string; cls: string }[] = []
|
||||
for (const error of schema.errors || []) {
|
||||
let name = toTitleCase(error.name)
|
||||
if (!name.endsWith('Error')) name += 'Error'
|
||||
const errCls = file.addClass({
|
||||
name,
|
||||
extends: 'XRPCError',
|
||||
isExported: true,
|
||||
})
|
||||
errCls
|
||||
.addConstructor({
|
||||
parameters: [{ name: 'src', type: 'XRPCError' }],
|
||||
})
|
||||
.setBodyText(`super(src.status, src.error, src.message)`)
|
||||
customErrors.push({ name: error.name, cls: name })
|
||||
}
|
||||
|
||||
// export function toKnownErr(err: any) {...}
|
||||
const toKnownErrFn = file.addFunction({
|
||||
name: 'toKnownErr',
|
||||
isExported: true,
|
||||
})
|
||||
toKnownErrFn.addParameter({ name: 'e', type: 'any' })
|
||||
toKnownErrFn.setBodyText(
|
||||
[
|
||||
`if (e instanceof XRPCError) {`,
|
||||
...customErrors.map(
|
||||
(err) => `if (e.error === '${err.name}') return new ${err.cls}(e)`,
|
||||
),
|
||||
`}`,
|
||||
`return e`,
|
||||
].join('\n'),
|
||||
)
|
||||
})
|
||||
|
||||
const recordSchemaTs = (project, schema: RecordSchema) =>
|
||||
|
@ -243,43 +243,62 @@ const methodSchemaTs = (project, schema: MethodSchema) =>
|
||||
)
|
||||
}
|
||||
|
||||
// export interface HandlerOutput {...}
|
||||
// export interface HandlerSuccess {...}
|
||||
let hasHandlerSuccess = false
|
||||
if (schema.output?.schema || schema.output?.encoding) {
|
||||
const handlerOutput = file.addInterface({
|
||||
name: 'HandlerOutput',
|
||||
hasHandlerSuccess = true
|
||||
const handlerSuccess = file.addInterface({
|
||||
name: 'HandlerSuccess',
|
||||
isExported: true,
|
||||
})
|
||||
if (Array.isArray(schema.output.encoding)) {
|
||||
handlerOutput.addProperty({
|
||||
handlerSuccess.addProperty({
|
||||
name: 'encoding',
|
||||
type: schema.output.encoding.map((v) => `'${v}'`).join(' | '),
|
||||
})
|
||||
} else if (typeof schema.output.encoding === 'string') {
|
||||
handlerOutput.addProperty({
|
||||
handlerSuccess.addProperty({
|
||||
name: 'encoding',
|
||||
type: `'${schema.output.encoding}'`,
|
||||
})
|
||||
}
|
||||
if (schema.output?.schema) {
|
||||
if (Array.isArray(schema.output.encoding)) {
|
||||
handlerOutput.addProperty({
|
||||
handlerSuccess.addProperty({
|
||||
name: 'body',
|
||||
type: 'OutputSchema | Uint8Array',
|
||||
})
|
||||
} else {
|
||||
handlerOutput.addProperty({ name: 'body', type: 'OutputSchema' })
|
||||
handlerSuccess.addProperty({ name: 'body', type: 'OutputSchema' })
|
||||
}
|
||||
} else if (schema.output?.encoding) {
|
||||
handlerOutput.addProperty({ name: 'body', type: 'Uint8Array' })
|
||||
handlerSuccess.addProperty({ name: 'body', type: 'Uint8Array' })
|
||||
}
|
||||
} else {
|
||||
file.addTypeAlias({
|
||||
isExported: true,
|
||||
name: 'HandlerOutput',
|
||||
type: 'void',
|
||||
}
|
||||
|
||||
// export interface HandlerError {...}
|
||||
const handlerError = file.addInterface({
|
||||
name: 'HandlerError',
|
||||
isExported: true,
|
||||
})
|
||||
handlerError.addProperties([
|
||||
{ name: 'status', type: 'number' },
|
||||
{ name: 'message?', type: 'string' },
|
||||
])
|
||||
if (schema.errors?.length) {
|
||||
handlerError.addProperty({
|
||||
name: 'error?',
|
||||
type: schema.errors.map((err) => `'${err.name}'`).join(' | '),
|
||||
})
|
||||
}
|
||||
|
||||
// export type HandlerOutput = ...
|
||||
file.addTypeAlias({
|
||||
isExported: true,
|
||||
name: 'HandlerOutput',
|
||||
type: `HandlerError | ${hasHandlerSuccess ? 'HandlerSuccess' : 'void'}`,
|
||||
})
|
||||
|
||||
//= export interface OutputSchema {...}
|
||||
if (schema.output?.schema) {
|
||||
file.insertText(
|
||||
|
@ -43,6 +43,12 @@ export const methodSchemaParam = z.object({
|
||||
})
|
||||
export type MethodSchemaParam = z.infer<typeof methodSchemaParam>
|
||||
|
||||
export const methodSchemaError = z.object({
|
||||
name: z.string(),
|
||||
description: z.string().optional(),
|
||||
})
|
||||
export type MethodSchemaError = z.infer<typeof methodSchemaError>
|
||||
|
||||
export const methodSchema = z.object({
|
||||
lexicon: z.literal(1),
|
||||
id: z.string(),
|
||||
@ -51,6 +57,7 @@ export const methodSchema = z.object({
|
||||
parameters: z.record(methodSchemaParam).optional(),
|
||||
input: methodSchemaBody.optional(),
|
||||
output: methodSchemaBody.optional(),
|
||||
errors: methodSchemaError.array().optional(),
|
||||
})
|
||||
export type MethodSchema = z.infer<typeof methodSchema>
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Server } from '../../../lexicon'
|
||||
import * as CreateAccount from '../../../lexicon/types/todo/adx/createAccount'
|
||||
import { InvalidRequestError } from '@adxp/xrpc-server'
|
||||
import * as util from '../../../util'
|
||||
import { Repo } from '@adxp/repo'
|
||||
@ -33,14 +34,17 @@ export default function (server: Server) {
|
||||
const cfg = util.getConfig(res)
|
||||
|
||||
if (username.startsWith('did:')) {
|
||||
throw new InvalidRequestError(
|
||||
'Cannot register a username that starts with `did:`',
|
||||
)
|
||||
return {
|
||||
status: 400,
|
||||
error: 'InvalidUsername',
|
||||
message: 'Cannot register a username that starts with `did:`',
|
||||
}
|
||||
}
|
||||
if (!did.startsWith('did:')) {
|
||||
throw new InvalidRequestError(
|
||||
'Cannot register a did that does not start with `did:`',
|
||||
)
|
||||
return {
|
||||
status: 400,
|
||||
message: 'Cannot register a did that does not start with `did:`',
|
||||
}
|
||||
}
|
||||
|
||||
let isTestUser = false
|
||||
|
@ -40,6 +40,17 @@ export const methodSchemas: MethodSchema[] = [
|
||||
},
|
||||
},
|
||||
},
|
||||
errors: [
|
||||
{
|
||||
name: 'InvalidUsername',
|
||||
},
|
||||
{
|
||||
name: 'InvalidPassword',
|
||||
},
|
||||
{
|
||||
name: 'UsernameNotAvailable',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
lexicon: 1,
|
||||
|
@ -16,11 +16,19 @@ export interface InputSchema {
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
error?: 'InvalidUsername' | 'InvalidPassword' | 'UsernameNotAvailable';
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
jwt: string;
|
||||
}
|
||||
|
@ -15,11 +15,18 @@ export interface InputSchema {
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
jwt: string;
|
||||
name: string;
|
||||
|
@ -11,11 +11,18 @@ export interface InputSchema {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: '';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
@ -11,11 +11,18 @@ export interface InputSchema {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: '';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
@ -11,11 +11,18 @@ export interface InputSchema {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: '';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
@ -7,11 +7,18 @@ export interface QueryParams {}
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
inviteCodeRequired?: boolean;
|
||||
availableUserDomains: string[];
|
||||
|
@ -7,11 +7,18 @@ export interface QueryParams {}
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
name: string;
|
||||
did: string;
|
||||
|
@ -34,11 +34,18 @@ export interface InputSchema {
|
||||
)[];
|
||||
}
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
@ -18,11 +18,18 @@ export interface InputSchema {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
uri: string;
|
||||
}
|
||||
|
@ -10,7 +10,13 @@ export interface QueryParams {
|
||||
}
|
||||
|
||||
export type HandlerInput = undefined
|
||||
export type HandlerOutput = void
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | void
|
||||
export type Handler = (
|
||||
params: QueryParams,
|
||||
input: HandlerInput,
|
||||
|
@ -9,11 +9,18 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
name: string;
|
||||
did: string;
|
||||
|
@ -11,11 +11,18 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
uri: string;
|
||||
value: {};
|
||||
|
@ -14,11 +14,18 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
records: {
|
||||
uri: string,
|
||||
|
@ -19,11 +19,18 @@ export interface InputSchema {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
uri: string;
|
||||
}
|
||||
|
@ -9,11 +9,18 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
did: string;
|
||||
}
|
||||
|
@ -10,11 +10,17 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/cbor';
|
||||
body: Uint8Array;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
export type Handler = (
|
||||
params: QueryParams,
|
||||
input: HandlerInput,
|
||||
|
@ -9,11 +9,18 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
root: string;
|
||||
}
|
||||
|
@ -12,7 +12,12 @@ export interface HandlerInput {
|
||||
body: Uint8Array;
|
||||
}
|
||||
|
||||
export type HandlerOutput = void
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | void
|
||||
export type Handler = (
|
||||
params: QueryParams,
|
||||
input: HandlerInput,
|
||||
|
@ -11,11 +11,18 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
feed: FeedItem[];
|
||||
}
|
||||
|
@ -11,11 +11,18 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
uri: string;
|
||||
likedBy: {
|
||||
|
@ -10,11 +10,18 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
notifications: Notification[];
|
||||
}
|
||||
|
@ -10,11 +10,18 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
thread: Post;
|
||||
}
|
||||
|
@ -9,11 +9,18 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
did: string;
|
||||
name: string;
|
||||
|
@ -11,11 +11,18 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
uri: string;
|
||||
repostedBy: {
|
||||
|
@ -11,11 +11,18 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
subject: {
|
||||
did: string,
|
||||
|
@ -11,11 +11,18 @@ export interface QueryParams {
|
||||
|
||||
export type HandlerInput = undefined
|
||||
|
||||
export interface HandlerOutput {
|
||||
export interface HandlerSuccess {
|
||||
encoding: 'application/json';
|
||||
body: OutputSchema;
|
||||
}
|
||||
|
||||
export interface HandlerError {
|
||||
status: number;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type HandlerOutput = HandlerError | HandlerSuccess
|
||||
|
||||
export interface OutputSchema {
|
||||
subject: {
|
||||
did: string,
|
||||
|
@ -1,4 +1,7 @@
|
||||
import AdxApi, { ServiceClient as AdxServiceClient } from '@adxp/api'
|
||||
import AdxApi, {
|
||||
ServiceClient as AdxServiceClient,
|
||||
TodoAdxCreateAccount,
|
||||
} from '@adxp/api'
|
||||
import * as util from './_util'
|
||||
|
||||
const username = 'alice.test'
|
||||
@ -33,6 +36,24 @@ describe('auth', () => {
|
||||
expect(typeof res.data.jwt).toBe('string')
|
||||
})
|
||||
|
||||
it('fails on invalid usernames', async () => {
|
||||
try {
|
||||
await client.todo.adx.createAccount(
|
||||
{},
|
||||
{
|
||||
username: 'did:bad-username.test',
|
||||
did: 'bad.test',
|
||||
password: 'asdf',
|
||||
},
|
||||
)
|
||||
throw new Error('Didnt throw')
|
||||
} catch (e: any) {
|
||||
expect(
|
||||
e instanceof TodoAdxCreateAccount.InvalidUsernameError,
|
||||
).toBeTruthy()
|
||||
}
|
||||
})
|
||||
|
||||
it('fails on authenticated requests', async () => {
|
||||
await expect(client.todo.adx.getSession({})).rejects.toThrow()
|
||||
})
|
||||
|
@ -1,7 +1,16 @@
|
||||
import express from 'express'
|
||||
import { ValidateFunction } from 'ajv'
|
||||
import { MethodSchema, methodSchema, isValidMethodSchema } from '@adxp/lexicon'
|
||||
import { XRPCHandler, XRPCError, InvalidRequestError } from './types'
|
||||
import {
|
||||
XRPCHandler,
|
||||
XRPCError,
|
||||
InvalidRequestError,
|
||||
HandlerOutput,
|
||||
HandlerSuccess,
|
||||
handlerSuccess,
|
||||
HandlerError,
|
||||
handlerError,
|
||||
} from './types'
|
||||
import {
|
||||
ajv,
|
||||
validateReqParams,
|
||||
@ -113,37 +122,43 @@ export class Server {
|
||||
// run the handler
|
||||
const outputUnvalidated = await handler(params, input, req, res)
|
||||
|
||||
// validate response
|
||||
const output = validateOutput(
|
||||
schema,
|
||||
outputUnvalidated,
|
||||
this.outputValidators.get(schema.id),
|
||||
)
|
||||
if (!outputUnvalidated || isHandlerSuccess(outputUnvalidated)) {
|
||||
// validate response
|
||||
const output = validateOutput(
|
||||
schema,
|
||||
outputUnvalidated,
|
||||
this.outputValidators.get(schema.id),
|
||||
)
|
||||
|
||||
// send response
|
||||
if (
|
||||
output?.encoding === 'application/json' ||
|
||||
output?.encoding === 'json'
|
||||
) {
|
||||
res.status(200).json(output.body)
|
||||
} else if (output) {
|
||||
res.header('Content-Type', output.encoding)
|
||||
res
|
||||
.status(200)
|
||||
.send(
|
||||
output.body instanceof Uint8Array
|
||||
? Buffer.from(output.body)
|
||||
: output.body,
|
||||
)
|
||||
} else {
|
||||
res.status(200).end()
|
||||
// send response
|
||||
if (
|
||||
output?.encoding === 'application/json' ||
|
||||
output?.encoding === 'json'
|
||||
) {
|
||||
res.status(200).json(output.body)
|
||||
} else if (output) {
|
||||
res.header('Content-Type', output.encoding)
|
||||
res
|
||||
.status(200)
|
||||
.send(
|
||||
output.body instanceof Uint8Array
|
||||
? Buffer.from(output.body)
|
||||
: output.body,
|
||||
)
|
||||
} else {
|
||||
res.status(200).end()
|
||||
}
|
||||
} else if (isHandlerError(outputUnvalidated)) {
|
||||
return res.status(outputUnvalidated.status).json({
|
||||
error: outputUnvalidated.error,
|
||||
message: outputUnvalidated.message,
|
||||
})
|
||||
}
|
||||
} catch (e: any) {
|
||||
if (e instanceof XRPCError) {
|
||||
res.status(e.type).json({
|
||||
error: true,
|
||||
type: e.typeStr,
|
||||
message: e.message || e.typeStr,
|
||||
error: e.customErrorName,
|
||||
message: e.errorMessage || e.typeStr,
|
||||
})
|
||||
} else {
|
||||
console.error(
|
||||
@ -151,11 +166,17 @@ export class Server {
|
||||
)
|
||||
console.error(e)
|
||||
res.status(500).json({
|
||||
error: true,
|
||||
type: 'InternalError',
|
||||
message: 'Unexpected internal server error',
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isHandlerSuccess(v: HandlerOutput): v is HandlerSuccess {
|
||||
return handlerSuccess.safeParse(v).success
|
||||
}
|
||||
|
||||
function isHandlerError(v: HandlerOutput): v is HandlerError {
|
||||
return handlerError.safeParse(v).success
|
||||
}
|
||||
|
@ -10,11 +10,20 @@ export const handlerInput = zod.object({
|
||||
})
|
||||
export type HandlerInput = zod.infer<typeof handlerInput>
|
||||
|
||||
export const handlerOutput = zod.object({
|
||||
export const handlerSuccess = zod.object({
|
||||
encoding: zod.string(),
|
||||
body: zod.any(),
|
||||
})
|
||||
export type HandlerOutput = zod.infer<typeof handlerOutput>
|
||||
export type HandlerSuccess = zod.infer<typeof handlerSuccess>
|
||||
|
||||
export const handlerError = zod.object({
|
||||
status: zod.number(),
|
||||
error: zod.string().optional(),
|
||||
message: zod.string().optional(),
|
||||
})
|
||||
export type HandlerError = zod.infer<typeof handlerError>
|
||||
|
||||
export type HandlerOutput = HandlerSuccess | HandlerError
|
||||
|
||||
export type XRPCHandler = (
|
||||
params: Params,
|
||||
@ -24,8 +33,12 @@ export type XRPCHandler = (
|
||||
) => Promise<HandlerOutput> | HandlerOutput | undefined
|
||||
|
||||
export class XRPCError extends Error {
|
||||
constructor(public type: ResponseType, message?: string) {
|
||||
super(message)
|
||||
constructor(
|
||||
public type: ResponseType,
|
||||
public errorMessage?: string,
|
||||
public customErrorName?: string,
|
||||
) {
|
||||
super(errorMessage)
|
||||
}
|
||||
|
||||
get typeStr() {
|
||||
@ -34,43 +47,43 @@ export class XRPCError extends Error {
|
||||
}
|
||||
|
||||
export class InvalidRequestError extends XRPCError {
|
||||
constructor(message?: string) {
|
||||
super(ResponseType.InvalidRequest, message)
|
||||
constructor(errorMessage?: string, customErrorName?: string) {
|
||||
super(ResponseType.InvalidRequest, errorMessage, customErrorName)
|
||||
}
|
||||
}
|
||||
|
||||
export class AuthRequiredError extends XRPCError {
|
||||
constructor(message?: string) {
|
||||
super(ResponseType.AuthRequired, message)
|
||||
constructor(errorMessage?: string, customErrorName?: string) {
|
||||
super(ResponseType.AuthRequired, errorMessage, customErrorName)
|
||||
}
|
||||
}
|
||||
|
||||
export class ForbiddenError extends XRPCError {
|
||||
constructor(message?: string) {
|
||||
super(ResponseType.Forbidden, message)
|
||||
constructor(errorMessage?: string, customErrorName?: string) {
|
||||
super(ResponseType.Forbidden, errorMessage, customErrorName)
|
||||
}
|
||||
}
|
||||
|
||||
export class InternalServerError extends XRPCError {
|
||||
constructor(message?: string) {
|
||||
super(ResponseType.InternalServerError, message)
|
||||
constructor(errorMessage?: string, customErrorName?: string) {
|
||||
super(ResponseType.InternalServerError, errorMessage, customErrorName)
|
||||
}
|
||||
}
|
||||
|
||||
export class UpstreamFailureError extends XRPCError {
|
||||
constructor(message?: string) {
|
||||
super(ResponseType.UpstreamFailure, message)
|
||||
constructor(errorMessage?: string, customErrorName?: string) {
|
||||
super(ResponseType.UpstreamFailure, errorMessage, customErrorName)
|
||||
}
|
||||
}
|
||||
|
||||
export class NotEnoughResoucesError extends XRPCError {
|
||||
constructor(message?: string) {
|
||||
super(ResponseType.NotEnoughResouces, message)
|
||||
constructor(errorMessage?: string, customErrorName?: string) {
|
||||
super(ResponseType.NotEnoughResouces, errorMessage, customErrorName)
|
||||
}
|
||||
}
|
||||
|
||||
export class UpstreamTimeoutError extends XRPCError {
|
||||
constructor(message?: string) {
|
||||
super(ResponseType.UpstreamTimeout, message)
|
||||
constructor(errorMessage?: string, customErrorName?: string) {
|
||||
super(ResponseType.UpstreamTimeout, errorMessage, customErrorName)
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ import addFormats from 'ajv-formats'
|
||||
import {
|
||||
Params,
|
||||
HandlerInput,
|
||||
HandlerOutput,
|
||||
handlerOutput,
|
||||
HandlerSuccess,
|
||||
handlerSuccess,
|
||||
InvalidRequestError,
|
||||
InternalServerError,
|
||||
} from './types'
|
||||
@ -144,12 +144,12 @@ export function validateInput(
|
||||
|
||||
export function validateOutput(
|
||||
schema: MethodSchema,
|
||||
output: HandlerOutput | undefined,
|
||||
output: HandlerSuccess | undefined,
|
||||
jsonValidator?: ValidateFunction,
|
||||
): HandlerOutput | undefined {
|
||||
): HandlerSuccess | undefined {
|
||||
// initial validation
|
||||
if (output) {
|
||||
handlerOutput.parse(output)
|
||||
handlerSuccess.parse(output)
|
||||
}
|
||||
|
||||
// response expectation
|
||||
|
74
packages/xrpc-server/tests/errors.test.ts
Normal file
74
packages/xrpc-server/tests/errors.test.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import * as http from 'http'
|
||||
import { createServer, closeServer } from './_util'
|
||||
import * as xrpcServer from '../src'
|
||||
import xrpc, { XRPCError } from '@adxp/xrpc'
|
||||
|
||||
const SCHEMAS = [
|
||||
{
|
||||
lexicon: 1,
|
||||
id: 'io.example.error',
|
||||
type: 'query',
|
||||
parameters: {
|
||||
which: { type: 'string', default: 'foo' },
|
||||
},
|
||||
errors: [{ name: 'Foo' }, { name: 'Bar' }],
|
||||
},
|
||||
]
|
||||
|
||||
describe('Procedures', () => {
|
||||
let s: http.Server
|
||||
const server = xrpcServer.createServer(SCHEMAS)
|
||||
server.method('io.example.error', (params: xrpcServer.Params) => {
|
||||
if (params.which === 'foo') {
|
||||
throw new xrpcServer.InvalidRequestError('It was this one!', 'Foo')
|
||||
} else if (params.which === 'bar') {
|
||||
return { status: 400, error: 'Bar', message: 'It was that one!' }
|
||||
} else {
|
||||
return { status: 400 }
|
||||
}
|
||||
})
|
||||
const client = xrpc.service(`http://localhost:8893`)
|
||||
xrpc.addSchemas(SCHEMAS)
|
||||
beforeAll(async () => {
|
||||
s = await createServer(8893, server)
|
||||
})
|
||||
afterAll(async () => {
|
||||
await closeServer(s)
|
||||
})
|
||||
|
||||
it('serves requests', async () => {
|
||||
try {
|
||||
await client.call('io.example.error', {
|
||||
which: 'foo',
|
||||
})
|
||||
throw new Error('Didnt throw')
|
||||
} catch (e: any) {
|
||||
expect(e instanceof XRPCError).toBeTruthy()
|
||||
expect(e.success).toBeFalsy()
|
||||
expect(e.error).toBe('Foo')
|
||||
expect(e.message).toBe('It was this one!')
|
||||
}
|
||||
try {
|
||||
await client.call('io.example.error', {
|
||||
which: 'bar',
|
||||
})
|
||||
throw new Error('Didnt throw')
|
||||
} catch (e: any) {
|
||||
expect(e instanceof XRPCError).toBeTruthy()
|
||||
expect(e.success).toBeFalsy()
|
||||
expect(e.error).toBe('Bar')
|
||||
expect(e.message).toBe('It was that one!')
|
||||
}
|
||||
try {
|
||||
await client.call('io.example.error', {
|
||||
which: 'other',
|
||||
})
|
||||
throw new Error('Didnt throw')
|
||||
} catch (e: any) {
|
||||
expect(e instanceof XRPCError).toBeTruthy()
|
||||
expect(e.success).toBeFalsy()
|
||||
expect(e.error).toBe('InvalidRequest')
|
||||
expect(e.message).toBe('Invalid Request')
|
||||
}
|
||||
})
|
||||
})
|
@ -99,7 +99,6 @@ describe('Procedures', () => {
|
||||
message: 'hello world',
|
||||
})
|
||||
expect(res1.success).toBeTruthy()
|
||||
expect(res1.error).toBeFalsy()
|
||||
expect(res1.headers['content-type']).toBe('text/plain; charset=utf-8')
|
||||
expect(res1.data).toBe('hello world')
|
||||
|
||||
@ -107,7 +106,6 @@ describe('Procedures', () => {
|
||||
encoding: 'text/plain',
|
||||
})
|
||||
expect(res2.success).toBeTruthy()
|
||||
expect(res2.error).toBeFalsy()
|
||||
expect(res2.headers['content-type']).toBe('text/plain; charset=utf-8')
|
||||
expect(res2.data).toBe('hello world')
|
||||
|
||||
@ -118,7 +116,6 @@ describe('Procedures', () => {
|
||||
{ encoding: 'application/octet-stream' },
|
||||
)
|
||||
expect(res3.success).toBeTruthy()
|
||||
expect(res3.error).toBeFalsy()
|
||||
expect(res3.headers['content-type']).toBe('application/octet-stream')
|
||||
expect(new TextDecoder().decode(res3.data)).toBe('hello world')
|
||||
|
||||
@ -128,7 +125,6 @@ describe('Procedures', () => {
|
||||
{ message: 'hello world' },
|
||||
)
|
||||
expect(res4.success).toBeTruthy()
|
||||
expect(res4.error).toBeFalsy()
|
||||
expect(res4.headers['content-type']).toBe('application/json; charset=utf-8')
|
||||
expect(res4.data?.message).toBe('hello world')
|
||||
})
|
||||
|
@ -67,7 +67,6 @@ describe('Queries', () => {
|
||||
message: 'hello world',
|
||||
})
|
||||
expect(res1.success).toBeTruthy()
|
||||
expect(res1.error).toBeFalsy()
|
||||
expect(res1.headers['content-type']).toBe('text/plain; charset=utf-8')
|
||||
expect(res1.data).toBe('hello world')
|
||||
|
||||
@ -75,7 +74,6 @@ describe('Queries', () => {
|
||||
message: 'hello world',
|
||||
})
|
||||
expect(res2.success).toBeTruthy()
|
||||
expect(res2.error).toBeFalsy()
|
||||
expect(res2.headers['content-type']).toBe('application/octet-stream')
|
||||
expect(new TextDecoder().decode(res2.data)).toBe('hello world')
|
||||
|
||||
@ -83,7 +81,6 @@ describe('Queries', () => {
|
||||
message: 'hello world',
|
||||
})
|
||||
expect(res3.success).toBeTruthy()
|
||||
expect(res3.error).toBeFalsy()
|
||||
expect(res3.headers['content-type']).toBe('application/json; charset=utf-8')
|
||||
expect(res3.data?.message).toBe('hello world')
|
||||
})
|
||||
|
@ -113,7 +113,7 @@ export class ServiceClient {
|
||||
return new XRPCResponse(res.body, res.headers)
|
||||
} else {
|
||||
if (res.body && isErrorResponseBody(res.body)) {
|
||||
throw new XRPCError(resCode, res.body.message)
|
||||
throw new XRPCError(resCode, res.body.error, res.body.message)
|
||||
} else {
|
||||
throw new XRPCError(resCode)
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ export type FetchHandler = (
|
||||
) => Promise<FetchHandlerResponse>
|
||||
|
||||
export const errorResponseBody = z.object({
|
||||
error: z.string().optional(),
|
||||
message: z.string().optional(),
|
||||
})
|
||||
export type ErrorResponseBody = z.infer<typeof errorResponseBody>
|
||||
@ -43,6 +44,22 @@ export enum ResponseType {
|
||||
UpstreamTimeout = 504,
|
||||
}
|
||||
|
||||
export const ResponseTypeNames = {
|
||||
[ResponseType.InvalidResponse]: 'InvalidResponse',
|
||||
[ResponseType.Success]: 'Success',
|
||||
[ResponseType.InvalidRequest]: 'InvalidRequest',
|
||||
[ResponseType.AuthRequired]: 'AuthenticationRequired',
|
||||
[ResponseType.Forbidden]: 'Forbidden',
|
||||
[ResponseType.XRPCNotSupported]: 'XRPCNotSupported',
|
||||
[ResponseType.PayloadTooLarge]: 'PayloadTooLarge',
|
||||
[ResponseType.RateLimitExceeded]: 'RateLimitExceeded',
|
||||
[ResponseType.InternalServerError]: 'InternalServerError',
|
||||
[ResponseType.MethodNotImplemented]: 'MethodNotImplemented',
|
||||
[ResponseType.UpstreamFailure]: 'UpstreamFailure',
|
||||
[ResponseType.NotEnoughResouces]: 'NotEnoughResouces',
|
||||
[ResponseType.UpstreamTimeout]: 'UpstreamTimeout',
|
||||
}
|
||||
|
||||
export const ResponseTypeStrings = {
|
||||
[ResponseType.InvalidResponse]: 'Invalid Response',
|
||||
[ResponseType.Success]: 'Success',
|
||||
@ -61,20 +78,21 @@ export const ResponseTypeStrings = {
|
||||
|
||||
export class XRPCResponse {
|
||||
success = true
|
||||
error = false
|
||||
|
||||
constructor(public data: any, public headers: Headers) {}
|
||||
}
|
||||
|
||||
export class XRPCError extends Error {
|
||||
success = false
|
||||
error = true
|
||||
|
||||
constructor(public code: ResponseType, message?: string) {
|
||||
super(
|
||||
message
|
||||
? `${ResponseTypeStrings[code]}: ${message}`
|
||||
: ResponseTypeStrings[code],
|
||||
)
|
||||
constructor(
|
||||
public status: ResponseType,
|
||||
public error?: string,
|
||||
message?: string,
|
||||
) {
|
||||
super(message || error || ResponseTypeStrings[status])
|
||||
if (!this.error) {
|
||||
this.error = ResponseTypeNames[status]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,5 +25,10 @@
|
||||
"jwt": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"errors": [
|
||||
{"name": "InvalidUsername"},
|
||||
{"name": "InvalidPassword"},
|
||||
{"name": "UsernameNotAvailable"}
|
||||
]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user