update package version and response return tyupe for delete domain api (#272)
This commit is contained in:
@@ -626,10 +626,10 @@
|
|||||||
{
|
{
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"nullable": false,
|
"nullable": true,
|
||||||
"example": 1
|
"example": 1
|
||||||
},
|
},
|
||||||
"required": true,
|
"required": false,
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path"
|
"in": "path"
|
||||||
}
|
}
|
||||||
@@ -643,152 +643,55 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "number",
|
"type": "number"
|
||||||
"description": "The ID of the domain",
|
|
||||||
"example": 1
|
|
||||||
},
|
},
|
||||||
"name": {
|
"success": {
|
||||||
"type": "string",
|
"type": "boolean"
|
||||||
"description": "The name of the domain",
|
|
||||||
"example": "example.com"
|
|
||||||
},
|
},
|
||||||
"teamId": {
|
"message": {
|
||||||
"type": "number",
|
|
||||||
"description": "The ID of the team",
|
|
||||||
"example": 1
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"NOT_STARTED",
|
|
||||||
"PENDING",
|
|
||||||
"SUCCESS",
|
|
||||||
"FAILED",
|
|
||||||
"TEMPORARY_FAILURE"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"region": {
|
|
||||||
"type": "string",
|
|
||||||
"default": "us-east-1"
|
|
||||||
},
|
|
||||||
"clickTracking": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"openTracking": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"publicKey": {
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
|
||||||
"dkimStatus": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true
|
|
||||||
},
|
|
||||||
"spfDetails": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true
|
|
||||||
},
|
|
||||||
"createdAt": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"updatedAt": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"dmarcAdded": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"isVerifying": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"errorMessage": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true
|
|
||||||
},
|
|
||||||
"subdomain": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true
|
|
||||||
},
|
|
||||||
"verificationError": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true
|
|
||||||
},
|
|
||||||
"lastCheckedTime": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true
|
|
||||||
},
|
|
||||||
"dnsRecords": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"MX",
|
|
||||||
"TXT"
|
|
||||||
],
|
|
||||||
"description": "DNS record type",
|
|
||||||
"example": "TXT"
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "DNS record name",
|
|
||||||
"example": "mail"
|
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "DNS record value",
|
|
||||||
"example": "v=spf1 include:amazonses.com ~all"
|
|
||||||
},
|
|
||||||
"ttl": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "DNS record TTL",
|
|
||||||
"example": "Auto"
|
|
||||||
},
|
|
||||||
"priority": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true,
|
|
||||||
"description": "DNS record priority",
|
|
||||||
"example": "10"
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"NOT_STARTED",
|
|
||||||
"PENDING",
|
|
||||||
"SUCCESS",
|
|
||||||
"FAILED",
|
|
||||||
"TEMPORARY_FAILURE"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"recommended": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Whether the record is recommended"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": [
|
|
||||||
"type",
|
|
||||||
"name",
|
|
||||||
"value",
|
|
||||||
"ttl",
|
|
||||||
"status"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
"id",
|
"id",
|
||||||
"name",
|
"success",
|
||||||
"teamId",
|
"message"
|
||||||
"status",
|
]
|
||||||
"publicKey",
|
}
|
||||||
"createdAt",
|
}
|
||||||
"updatedAt",
|
}
|
||||||
"dnsRecords"
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden - API key doesn't have access",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"error": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"error"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Domain not found",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"error": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"error"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-23
@@ -34,23 +34,15 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "Self Hosting",
|
"group": "Self Hosting",
|
||||||
"pages": [
|
"pages": ["self-hosting/overview", "self-hosting/railway"]
|
||||||
"self-hosting/overview",
|
|
||||||
"self-hosting/railway"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "Guides",
|
"group": "Guides",
|
||||||
"pages": [
|
"pages": ["guides/use-with-react-email"]
|
||||||
"guides/use-with-react-email"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "Community SDKs",
|
"group": "Community SDKs",
|
||||||
"pages": [
|
"pages": ["community-sdk/python", "community-sdk/go"]
|
||||||
"community-sdk/python",
|
|
||||||
"community-sdk/go"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -59,9 +51,7 @@
|
|||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "API Reference",
|
"group": "API Reference",
|
||||||
"pages": [
|
"pages": ["api-reference/introduction"]
|
||||||
"api-reference/introduction"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "Emails",
|
"group": "Emails",
|
||||||
@@ -91,7 +81,8 @@
|
|||||||
"api-reference/domains/get-domain",
|
"api-reference/domains/get-domain",
|
||||||
"api-reference/domains/list-domains",
|
"api-reference/domains/list-domains",
|
||||||
"api-reference/domains/create-domain",
|
"api-reference/domains/create-domain",
|
||||||
"api-reference/domains/verify-domain"
|
"api-reference/domains/verify-domain",
|
||||||
|
"api-reference/domains/delete-domain"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -147,12 +138,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"contextual": {
|
"contextual": {
|
||||||
"options": [
|
"options": ["copy", "view", "chatgpt", "claude", "perplexity"]
|
||||||
"copy",
|
|
||||||
"view",
|
|
||||||
"chatgpt",
|
|
||||||
"claude",
|
|
||||||
"perplexity"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,83 +5,90 @@ import { UnsendApiError } from "../../api-error";
|
|||||||
import { deleteDomain as deleteDomainService } from "~/server/service/domain-service";
|
import { deleteDomain as deleteDomainService } from "~/server/service/domain-service";
|
||||||
|
|
||||||
const route = createRoute({
|
const route = createRoute({
|
||||||
method: "delete",
|
method: "delete",
|
||||||
path: "/v1/domains/{id}",
|
path: "/v1/domains/{id}",
|
||||||
request: {
|
request: {
|
||||||
params: z.object({
|
params: z.object({
|
||||||
id: z.coerce.number().openapi({
|
id: z.coerce.number().openapi({
|
||||||
param: {
|
param: {
|
||||||
name: "id",
|
name: "id",
|
||||||
in: "path",
|
in: "path",
|
||||||
},
|
},
|
||||||
example: 1,
|
example: 1,
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
content: {
|
||||||
|
"application/json": {
|
||||||
|
schema: z.object({
|
||||||
|
id: z.number(),
|
||||||
|
success: z.boolean(),
|
||||||
|
message: z.string(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: "Domain deleted successfully",
|
||||||
},
|
},
|
||||||
responses: {
|
403: {
|
||||||
200: {
|
content: {
|
||||||
content: {
|
"application/json": {
|
||||||
"application/json": {
|
schema: z.object({
|
||||||
schema: z.object({
|
error: z.string(),
|
||||||
success: z.boolean(),
|
}),
|
||||||
message: z.string(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description: "Domain deleted successfully",
|
|
||||||
},
|
},
|
||||||
403: {
|
},
|
||||||
"application/json": {
|
description: "Forbidden - API key doesn't have access",
|
||||||
schema: z.object({
|
},
|
||||||
error: z.string(),
|
404: {
|
||||||
}),
|
content: {
|
||||||
},
|
"application/json": {
|
||||||
description: "Forbidden - API key doesn't have access",
|
schema: z.object({
|
||||||
|
error: z.string(),
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
404: {
|
},
|
||||||
content: {
|
description: "Domain not found",
|
||||||
"application/json": {
|
},
|
||||||
schema: z.object({
|
},
|
||||||
error: z.string(),
|
});
|
||||||
}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description: "Domain not found",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
function deleteDomain(app: PublicAPIApp) {
|
function deleteDomain(app: PublicAPIApp) {
|
||||||
app.openapi(route, async (c) => {
|
app.openapi(route, async (c) => {
|
||||||
const team = c.var.team;
|
const team = c.var.team;
|
||||||
const domainId = c.req.valid("param").id;
|
const domainId = c.req.valid("param").id;
|
||||||
|
|
||||||
// Enforce API key domain restriction
|
// Enforce API key domain restriction
|
||||||
if (team.apiKey.domainId && team.apiKey.domainId !== domainId) {
|
if (team.apiKey.domainId && team.apiKey.domainId !== domainId) {
|
||||||
throw new UnsendApiError({
|
throw new UnsendApiError({
|
||||||
code: "FORBIDDEN",
|
code: "FORBIDDEN",
|
||||||
message: "API key doesn't have access to this domain",
|
message: "API key doesn't have access to this domain",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const domain = await db.domain.findFirst({
|
const domain = await db.domain.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: domainId,
|
id: domainId,
|
||||||
teamId: team.id
|
teamId: team.id,
|
||||||
},
|
},
|
||||||
});
|
|
||||||
|
|
||||||
if (!domain) {
|
|
||||||
throw new UnsendApiError({
|
|
||||||
code: "NOT_FOUND",
|
|
||||||
message: "Domain not found",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const deletedDomain = await deleteDomainService(domainId);
|
|
||||||
|
|
||||||
return c.json(deletedDomain);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!domain) {
|
||||||
|
throw new UnsendApiError({
|
||||||
|
code: "NOT_FOUND",
|
||||||
|
message: "Domain not found",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const deletedDomain = await deleteDomainService(domainId);
|
||||||
|
|
||||||
|
return c.json({
|
||||||
|
id: deletedDomain.id,
|
||||||
|
success: true,
|
||||||
|
message: "Domain deleted successfully",
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default deleteDomain;
|
export default deleteDomain;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "usesend"
|
name = "usesend"
|
||||||
version = "0.2.5"
|
version = "0.2.6"
|
||||||
description = "Python SDK for the UseSend API"
|
description = "Python SDK for the UseSend API"
|
||||||
authors = ["UseSend"]
|
authors = ["UseSend"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from .types import (
|
|||||||
Domain,
|
Domain,
|
||||||
DomainCreate,
|
DomainCreate,
|
||||||
DomainCreateResponse,
|
DomainCreateResponse,
|
||||||
|
DomainDeleteResponse,
|
||||||
DomainVerifyResponse,
|
DomainVerifyResponse,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ class Domains:
|
|||||||
data, err = self.usesend.get(f"/domains/{domain_id}")
|
data, err = self.usesend.get(f"/domains/{domain_id}")
|
||||||
return (data, err) # type: ignore[return-value]
|
return (data, err) # type: ignore[return-value]
|
||||||
|
|
||||||
def delete(self, domain_id: int) -> Tuple[Optional[Domain], Optional[APIError]]:
|
def delete(self, domain_id: int) -> Tuple[Optional[DomainDeleteResponse], Optional[APIError]]:
|
||||||
data, err = self.usesend.delete(f"/domains/{domain_id}")
|
data, err = self.usesend.delete(f"/domains/{domain_id}")
|
||||||
return (data, err) # type: ignore[return-value]
|
return (data, err) # type: ignore[return-value]
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,11 @@ class DomainVerifyResponse(TypedDict):
|
|||||||
message: str
|
message: str
|
||||||
|
|
||||||
|
|
||||||
|
class DomainDeleteResponse(TypedDict):
|
||||||
|
id: int
|
||||||
|
success: bool
|
||||||
|
message: str
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Emails
|
# Emails
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "usesend-js",
|
"name": "usesend-js",
|
||||||
"version": "1.5.4",
|
"version": "1.5.5",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"module": "./dist/index.mjs",
|
"module": "./dist/index.mjs",
|
||||||
|
|||||||
Vendored
+4
-69
@@ -369,7 +369,7 @@ export interface paths {
|
|||||||
query?: never;
|
query?: never;
|
||||||
header?: never;
|
header?: never;
|
||||||
path: {
|
path: {
|
||||||
id: number;
|
id: number | null;
|
||||||
};
|
};
|
||||||
cookie?: never;
|
cookie?: never;
|
||||||
};
|
};
|
||||||
@@ -382,78 +382,13 @@ export interface paths {
|
|||||||
};
|
};
|
||||||
content: {
|
content: {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
/**
|
|
||||||
* @description The ID of the domain
|
|
||||||
* @example 1
|
|
||||||
*/
|
|
||||||
id: number;
|
id: number;
|
||||||
/**
|
success: boolean;
|
||||||
* @description The name of the domain
|
message: string;
|
||||||
* @example example.com
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
/**
|
|
||||||
* @description The ID of the team
|
|
||||||
* @example 1
|
|
||||||
*/
|
|
||||||
teamId: number;
|
|
||||||
/** @enum {string} */
|
|
||||||
status: "NOT_STARTED" | "PENDING" | "SUCCESS" | "FAILED" | "TEMPORARY_FAILURE";
|
|
||||||
/** @default us-east-1 */
|
|
||||||
region: string;
|
|
||||||
/** @default false */
|
|
||||||
clickTracking: boolean;
|
|
||||||
/** @default false */
|
|
||||||
openTracking: boolean;
|
|
||||||
publicKey: string;
|
|
||||||
dkimStatus?: string | null;
|
|
||||||
spfDetails?: string | null;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
/** @default false */
|
|
||||||
dmarcAdded: boolean;
|
|
||||||
/** @default false */
|
|
||||||
isVerifying: boolean;
|
|
||||||
errorMessage?: string | null;
|
|
||||||
subdomain?: string | null;
|
|
||||||
verificationError?: string | null;
|
|
||||||
lastCheckedTime?: string | null;
|
|
||||||
dnsRecords: {
|
|
||||||
/**
|
|
||||||
* @description DNS record type
|
|
||||||
* @example TXT
|
|
||||||
* @enum {string}
|
|
||||||
*/
|
|
||||||
type: "MX" | "TXT";
|
|
||||||
/**
|
|
||||||
* @description DNS record name
|
|
||||||
* @example mail
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
/**
|
|
||||||
* @description DNS record value
|
|
||||||
* @example v=spf1 include:amazonses.com ~all
|
|
||||||
*/
|
|
||||||
value: string;
|
|
||||||
/**
|
|
||||||
* @description DNS record TTL
|
|
||||||
* @example Auto
|
|
||||||
*/
|
|
||||||
ttl: string;
|
|
||||||
/**
|
|
||||||
* @description DNS record priority
|
|
||||||
* @example 10
|
|
||||||
*/
|
|
||||||
priority?: string | null;
|
|
||||||
/** @enum {string} */
|
|
||||||
status: "NOT_STARTED" | "PENDING" | "SUCCESS" | "FAILED" | "TEMPORARY_FAILURE";
|
|
||||||
/** @description Whether the record is recommended */
|
|
||||||
recommended?: boolean;
|
|
||||||
}[];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
/** @description Forbidden - API key doesn't have access to this domain */
|
/** @description Forbidden - API key doesn't have access */
|
||||||
403: {
|
403: {
|
||||||
headers: {
|
headers: {
|
||||||
[name: string]: unknown;
|
[name: string]: unknown;
|
||||||
|
|||||||
Reference in New Issue
Block a user