Fix custom parser OpenAPI types and add structured default response schema

Agent-Logs-Url: https://github.com/fosrl/pangolin/sessions/73990123-9c27-444b-bc6e-77e890a0d57c

Co-authored-by: oschwartz10612 <4999704+oschwartz10612@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-05-17 06:38:44 +00:00
committed by GitHub
parent 82745c701a
commit 9cec711427
66 changed files with 98 additions and 76 deletions

View File

@@ -152,11 +152,17 @@ function getOpenApiDocumentation() {
if (!hasExistingResponses) { if (!hasExistingResponses) {
def.route.responses = { def.route.responses = {
"*": { "200": {
description: "", description: "Successful response",
content: { content: {
"application/json": { "application/json": {
schema: z.object({}) schema: z.object({
data: z.unknown().nullable(),
success: z.boolean(),
error: z.boolean(),
message: z.string(),
status: z.number()
})
} }
} }
} }

View File

@@ -873,7 +873,13 @@ export const portRangeStringSchema = z
message: message:
'Port range must be "*" for all ports, or a comma-separated list of ports and ranges (e.g., "80,443,8000-9000"). Ports must be between 1 and 65535, and ranges must have start <= end.' 'Port range must be "*" for all ports, or a comma-separated list of ports and ranges (e.g., "80,443,8000-9000"). Ports must be between 1 and 65535, and ranges must have start <= end.'
} }
); )
.openapi({
type: "string",
description:
'Port range string. Use "*" for all ports, a comma-separated list of ports, or ranges (e.g., "80,443,8000-9000"). Ports must be between 1 and 65535.',
example: "80,443,8000-9000"
});
/** /**
* Parses a port range string into an array of port range objects * Parses a port range string into an array of port range objects

View File

@@ -24,7 +24,7 @@ import type { NextFunction, Request, Response } from "express";
const paramsSchema = z.strictObject({ const paramsSchema = z.strictObject({
orgId: z.string(), orgId: z.string(),
approvalId: z.string().transform(Number).pipe(z.int().positive()) approvalId: z.coerce.number().int().positive()
}); });
const bodySchema = z.strictObject({ const bodySchema = z.strictObject({

View File

@@ -25,7 +25,7 @@ import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const restartCertificateParamsSchema = z.strictObject({ const restartCertificateParamsSchema = z.strictObject({
certId: z.string().transform(stoi).pipe(z.int().positive()), certId: z.coerce.number().int().positive(),
orgId: z.string() orgId: z.string()
}); });
@@ -36,7 +36,7 @@ registry.registerPath({
tags: ["Certificate"], tags: ["Certificate"],
request: { request: {
params: z.object({ params: z.object({
certId: z.string().transform(stoi).pipe(z.int().positive()), certId: z.coerce.number().int().positive(),
orgId: z.string() orgId: z.string()
}) })
}, },

View File

@@ -28,7 +28,7 @@ import { OlmErrorCodes, sendOlmError } from "@server/routers/olm/error";
import { sendTerminateClient } from "@server/routers/client/terminate"; import { sendTerminateClient } from "@server/routers/client/terminate";
const reGenerateSecretParamsSchema = z.strictObject({ const reGenerateSecretParamsSchema = z.strictObject({
clientId: z.string().transform(Number).pipe(z.int().positive()) clientId: z.coerce.number().int().positive()
}); });
const reGenerateSecretBodySchema = z.strictObject({ const reGenerateSecretBodySchema = z.strictObject({

View File

@@ -27,7 +27,7 @@ import { getAllowedIps } from "@server/routers/target/helpers";
import { disconnectClient, sendToClient } from "#private/routers/ws"; import { disconnectClient, sendToClient } from "#private/routers/ws";
const updateSiteParamsSchema = z.strictObject({ const updateSiteParamsSchema = z.strictObject({
siteId: z.string().transform(Number).pipe(z.int().positive()) siteId: z.coerce.number().int().positive()
}); });
const updateSiteBodySchema = z.strictObject({ const updateSiteBodySchema = z.strictObject({

View File

@@ -27,7 +27,7 @@ import { rebuildClientAssociationsFromClient } from "@server/lib/rebuildClientAs
const addUserRoleParamsSchema = z.strictObject({ const addUserRoleParamsSchema = z.strictObject({
userId: z.string(), userId: z.string(),
roleId: z.string().transform(stoi).pipe(z.number()) roleId: z.coerce.number()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -27,7 +27,7 @@ import { rebuildClientAssociationsFromClient } from "@server/lib/rebuildClientAs
const removeUserRoleParamsSchema = z.strictObject({ const removeUserRoleParamsSchema = z.strictObject({
userId: z.string(), userId: z.string(),
roleId: z.string().transform(stoi).pipe(z.number()) roleId: z.coerce.number()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -31,7 +31,7 @@ export const generateAccessTokenBodySchema = z.strictObject({
}); });
export const generateAccssTokenParamsSchema = z.strictObject({ export const generateAccssTokenParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
export type GenerateAccessTokenResponse = Omit< export type GenerateAccessTokenResponse = Omit<

View File

@@ -9,7 +9,7 @@ import logger from "@server/logger";
export const params = z.strictObject({ export const params = z.strictObject({
token: z.string(), token: z.string(),
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
export type CheckResourceSessionParams = z.infer<typeof params>; export type CheckResourceSessionParams = z.infer<typeof params>;

View File

@@ -13,7 +13,7 @@ import { OpenAPITags, registry } from "@server/openApi";
import { BlueprintData } from "./types"; import { BlueprintData } from "./types";
const getBlueprintSchema = z.strictObject({ const getBlueprintSchema = z.strictObject({
blueprintId: z.string().transform(stoi).pipe(z.int().positive()), blueprintId: z.coerce.number().int().positive(),
orgId: z.string() orgId: z.string()
}); });

View File

@@ -11,7 +11,7 @@ import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const archiveClientSchema = z.strictObject({ const archiveClientSchema = z.strictObject({
clientId: z.string().transform(Number).pipe(z.int().positive()) clientId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -13,7 +13,7 @@ import { sendTerminateClient } from "./terminate";
import { OlmErrorCodes } from "../olm/error"; import { OlmErrorCodes } from "../olm/error";
const blockClientSchema = z.strictObject({ const blockClientSchema = z.strictObject({
clientId: z.string().transform(Number).pipe(z.int().positive()) clientId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -14,7 +14,7 @@ import { sendTerminateClient } from "./terminate";
import { OlmErrorCodes } from "../olm/error"; import { OlmErrorCodes } from "../olm/error";
const deleteClientSchema = z.strictObject({ const deleteClientSchema = z.strictObject({
clientId: z.string().transform(Number).pipe(z.int().positive()) clientId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -11,7 +11,7 @@ import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const unarchiveClientSchema = z.strictObject({ const unarchiveClientSchema = z.strictObject({
clientId: z.string().transform(Number).pipe(z.int().positive()) clientId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -11,7 +11,7 @@ import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const unblockClientSchema = z.strictObject({ const unblockClientSchema = z.strictObject({
clientId: z.string().transform(Number).pipe(z.int().positive()) clientId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -11,7 +11,7 @@ import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const updateClientParamsSchema = z.strictObject({ const updateClientParamsSchema = z.strictObject({
clientId: z.string().transform(Number).pipe(z.int().positive()) clientId: z.coerce.number().int().positive()
}); });
const updateClientSchema = z.strictObject({ const updateClientSchema = z.strictObject({

View File

@@ -22,7 +22,7 @@ const addEmailToResourceWhitelistBodySchema = z.strictObject({
}); });
const addEmailToResourceWhitelistParamsSchema = z.strictObject({ const addEmailToResourceWhitelistParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -20,7 +20,7 @@ export const authWithPasswordBodySchema = z.strictObject({
}); });
export const authWithPasswordParamsSchema = z.strictObject({ export const authWithPasswordParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
export type AuthWithPasswordResponse = { export type AuthWithPasswordResponse = {

View File

@@ -19,7 +19,7 @@ export const authWithPincodeBodySchema = z.strictObject({
}); });
export const authWithPincodeParamsSchema = z.strictObject({ export const authWithPincodeParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
export type AuthWithPincodeResponse = { export type AuthWithPincodeResponse = {

View File

@@ -20,7 +20,7 @@ const authWithWhitelistBodySchema = z.strictObject({
}); });
const authWithWhitelistParamsSchema = z.strictObject({ const authWithWhitelistParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
export type AuthWithWhitelistResponse = { export type AuthWithWhitelistResponse = {

View File

@@ -25,7 +25,7 @@ const createResourceRuleSchema = z.strictObject({
}); });
const createResourceRuleParamsSchema = z.strictObject({ const createResourceRuleParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -15,7 +15,7 @@ import { OpenAPITags, registry } from "@server/openApi";
// Define Zod schema for request parameters validation // Define Zod schema for request parameters validation
const deleteResourceSchema = z.strictObject({ const deleteResourceSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -11,8 +11,8 @@ import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const deleteResourceRuleSchema = z.strictObject({ const deleteResourceRuleSchema = z.strictObject({
ruleId: z.string().transform(Number).pipe(z.int().positive()), ruleId: z.coerce.number().int().positive(),
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -17,7 +17,7 @@ import { checkOrgAccessPolicy } from "#dynamic/lib/checkOrgAccessPolicy";
import { logAccessAudit } from "#dynamic/lib/logAccessAudit"; import { logAccessAudit } from "#dynamic/lib/logAccessAudit";
const getExchangeTokenParams = z.strictObject({ const getExchangeTokenParams = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
export type GetExchangeTokenResponse = { export type GetExchangeTokenResponse = {

View File

@@ -11,7 +11,7 @@ import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const getResourceWhitelistSchema = z.strictObject({ const getResourceWhitelistSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
async function queryWhitelist(resourceId: number) { async function queryWhitelist(resourceId: number) {

View File

@@ -11,7 +11,7 @@ import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const listResourceRolesSchema = z.strictObject({ const listResourceRolesSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
async function query(resourceId: number) { async function query(resourceId: number) {

View File

@@ -11,7 +11,7 @@ import logger from "@server/logger";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const listResourceRulesParamsSchema = z.strictObject({ const listResourceRulesParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
const listResourceRulesSchema = z.object({ const listResourceRulesSchema = z.object({

View File

@@ -11,7 +11,7 @@ import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const listResourceUsersSchema = z.strictObject({ const listResourceUsersSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
async function queryUsers(resourceId: number) { async function queryUsers(resourceId: number) {

View File

@@ -22,7 +22,7 @@ const removeEmailFromResourceWhitelistBodySchema = z.strictObject({
}); });
const removeEmailFromResourceWhitelistParamsSchema = z.strictObject({ const removeEmailFromResourceWhitelistParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -15,7 +15,7 @@ import { hashPassword } from "@server/auth/password";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const setResourceAuthMethodsParamsSchema = z.object({ const setResourceAuthMethodsParamsSchema = z.object({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
const setResourceAuthMethodsBodySchema = z.strictObject({ const setResourceAuthMethodsBodySchema = z.strictObject({

View File

@@ -13,7 +13,7 @@ import { hashPassword } from "@server/auth/password";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const setResourceAuthMethodsParamsSchema = z.object({ const setResourceAuthMethodsParamsSchema = z.object({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
const setResourceAuthMethodsBodySchema = z.strictObject({ const setResourceAuthMethodsBodySchema = z.strictObject({

View File

@@ -14,7 +14,7 @@ import { hashPassword } from "@server/auth/password";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const setResourceAuthMethodsParamsSchema = z.object({ const setResourceAuthMethodsParamsSchema = z.object({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
const setResourceAuthMethodsBodySchema = z.strictObject({ const setResourceAuthMethodsBodySchema = z.strictObject({

View File

@@ -15,7 +15,7 @@ const setResourceRolesBodySchema = z.strictObject({
}); });
const setResourceRolesParamsSchema = z.strictObject({ const setResourceRolesParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -15,7 +15,7 @@ const setUserResourcesBodySchema = z.strictObject({
}); });
const setUserResourcesParamsSchema = z.strictObject({ const setUserResourcesParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -24,7 +24,7 @@ const setResourceWhitelistBodySchema = z.strictObject({
}); });
const setResourceWhitelistParamsSchema = z.strictObject({ const setResourceWhitelistParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -31,7 +31,7 @@ import { tierMatrix } from "@server/lib/billing/tierMatrix";
import { isSubscribed } from "#dynamic/lib/isSubscribed"; import { isSubscribed } from "#dynamic/lib/isSubscribed";
const updateResourceParamsSchema = z.strictObject({ const updateResourceParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
const updateHttpResourceBodySchema = z const updateHttpResourceBodySchema = z

View File

@@ -18,8 +18,8 @@ import { isValidRegionId } from "@server/db/regions";
// Define Zod schema for request parameters validation // Define Zod schema for request parameters validation
const updateResourceRuleParamsSchema = z.strictObject({ const updateResourceRuleParamsSchema = z.strictObject({
ruleId: z.string().transform(Number).pipe(z.int().positive()), ruleId: z.coerce.number().int().positive(),
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
// Define Zod schema for request body validation // Define Zod schema for request body validation

View File

@@ -10,7 +10,7 @@ import { eq } from "drizzle-orm";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
const addRoleActionParamSchema = z.strictObject({ const addRoleActionParamSchema = z.strictObject({
roleId: z.string().transform(Number).pipe(z.int().positive()) roleId: z.coerce.number().int().positive()
}); });
const addRoleActionSchema = z.strictObject({ const addRoleActionSchema = z.strictObject({

View File

@@ -10,11 +10,11 @@ import { eq } from "drizzle-orm";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
const addRoleSiteParamsSchema = z.strictObject({ const addRoleSiteParamsSchema = z.strictObject({
roleId: z.string().transform(Number).pipe(z.int().positive()) roleId: z.coerce.number().int().positive()
}); });
const addRoleSiteSchema = z.strictObject({ const addRoleSiteSchema = z.strictObject({
siteId: z.string().transform(Number).pipe(z.int().positive()) siteId: z.coerce.number().int().positive()
}); });
export async function addRoleSite( export async function addRoleSite(

View File

@@ -11,11 +11,11 @@ import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const deleteRoleSchema = z.strictObject({ const deleteRoleSchema = z.strictObject({
roleId: z.string().transform(Number).pipe(z.int().positive()) roleId: z.coerce.number().int().positive()
}); });
const deelteRoleBodySchema = z.strictObject({ const deelteRoleBodySchema = z.strictObject({
roleId: z.string().transform(Number).pipe(z.int().positive()) roleId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -11,7 +11,7 @@ import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const getRoleSchema = z.strictObject({ const getRoleSchema = z.strictObject({
roleId: z.string().transform(Number).pipe(z.int().positive()) roleId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -10,7 +10,7 @@ import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
const listRoleActionsSchema = z.strictObject({ const listRoleActionsSchema = z.strictObject({
roleId: z.string().transform(Number).pipe(z.int().positive()) roleId: z.coerce.number().int().positive()
}); });
export async function listRoleActions( export async function listRoleActions(

View File

@@ -10,7 +10,7 @@ import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
const listRoleResourcesSchema = z.strictObject({ const listRoleResourcesSchema = z.strictObject({
roleId: z.string().transform(Number).pipe(z.int().positive()) roleId: z.coerce.number().int().positive()
}); });
export async function listRoleResources( export async function listRoleResources(

View File

@@ -10,7 +10,7 @@ import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
const listRoleSitesSchema = z.strictObject({ const listRoleSitesSchema = z.strictObject({
roleId: z.string().transform(Number).pipe(z.int().positive()) roleId: z.coerce.number().int().positive()
}); });
export async function listRoleSites( export async function listRoleSites(

View File

@@ -10,7 +10,7 @@ import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
const removeRoleActionParamsSchema = z.strictObject({ const removeRoleActionParamsSchema = z.strictObject({
roleId: z.string().transform(Number).pipe(z.int().positive()) roleId: z.coerce.number().int().positive()
}); });
const removeRoleActionSchema = z.strictObject({ const removeRoleActionSchema = z.strictObject({

View File

@@ -10,11 +10,11 @@ import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
const removeRoleResourceParamsSchema = z.strictObject({ const removeRoleResourceParamsSchema = z.strictObject({
roleId: z.string().transform(Number).pipe(z.int().positive()) roleId: z.coerce.number().int().positive()
}); });
const removeRoleResourceSchema = z.strictObject({ const removeRoleResourceSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
export async function removeRoleResource( export async function removeRoleResource(

View File

@@ -10,11 +10,11 @@ import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
const removeRoleSiteParamsSchema = z.strictObject({ const removeRoleSiteParamsSchema = z.strictObject({
roleId: z.string().transform(Number).pipe(z.int().positive()) roleId: z.coerce.number().int().positive()
}); });
const removeRoleSiteSchema = z.strictObject({ const removeRoleSiteSchema = z.strictObject({
siteId: z.string().transform(Number).pipe(z.int().positive()) siteId: z.coerce.number().int().positive()
}); });
export async function removeRoleSite( export async function removeRoleSite(

View File

@@ -14,7 +14,7 @@ import { OpenAPITags, registry } from "@server/openApi";
import { tierMatrix } from "@server/lib/billing/tierMatrix"; import { tierMatrix } from "@server/lib/billing/tierMatrix";
const updateRoleParamsSchema = z.strictObject({ const updateRoleParamsSchema = z.strictObject({
roleId: z.string().transform(Number).pipe(z.int().positive()) roleId: z.coerce.number().int().positive()
}); });
const sshSudoModeSchema = z.enum(["none", "full", "commands"]); const sshSudoModeSchema = z.enum(["none", "full", "commands"]);

View File

@@ -16,7 +16,7 @@ import { usageService } from "@server/lib/billing/usageService";
import { FeatureId } from "@server/lib/billing"; import { FeatureId } from "@server/lib/billing";
const deleteSiteSchema = z.strictObject({ const deleteSiteSchema = z.strictObject({
siteId: z.string().transform(Number).pipe(z.int().positive()) siteId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -10,7 +10,7 @@ import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
const listSiteRolesSchema = z.strictObject({ const listSiteRolesSchema = z.strictObject({
siteId: z.string().transform(Number).pipe(z.int().positive()) siteId: z.coerce.number().int().positive()
}); });
export async function listSiteRoles( export async function listSiteRoles(

View File

@@ -44,7 +44,7 @@ export interface Container {
} }
const siteIdParamsSchema = z.strictObject({ const siteIdParamsSchema = z.strictObject({
siteId: z.string().transform(stoi).pipe(z.int().positive()) siteId: z.coerce.number().int().positive()
}); });
const DockerStatusSchema = z.strictObject({ const DockerStatusSchema = z.strictObject({

View File

@@ -12,7 +12,7 @@ import { OpenAPITags, registry } from "@server/openApi";
import { isValidCIDR } from "@server/lib/validators"; import { isValidCIDR } from "@server/lib/validators";
const updateSiteParamsSchema = z.strictObject({ const updateSiteParamsSchema = z.strictObject({
siteId: z.string().transform(Number).pipe(z.int().positive()) siteId: z.coerce.number().int().positive()
}); });
const updateSiteBodySchema = z const updateSiteBodySchema = z

View File

@@ -22,7 +22,7 @@ import {
const batchAddClientToSiteResourcesParamsSchema = z const batchAddClientToSiteResourcesParamsSchema = z
.object({ .object({
clientId: z.string().transform(Number).pipe(z.number().int().positive()) clientId: z.coerce.number().int().positive()
}) })
.strict(); .strict();

View File

@@ -42,7 +42,12 @@ const createSiteResourceParamsSchema = z.strictObject({
const createSiteResourceSchema = z const createSiteResourceSchema = z
.strictObject({ .strictObject({
name: z.string().min(1).max(255), name: z.string().min(1).max(255),
niceId: z.string().optional(), niceId: z.string().optional()
.openapi({
description:
"Fully qualified domain name with optional wildcards, e.g., example.internal, *.example.internal, or host-0?.example.internal",
example: "service.example.internal"
}),
// protocol: z.enum(["tcp", "udp"]).optional(), // protocol: z.enum(["tcp", "udp"]).optional(),
mode: z.enum(["host", "cidr", "http"]), mode: z.enum(["host", "cidr", "http"]),
ssl: z.boolean().optional(), // only used for http mode ssl: z.boolean().optional(), // only used for http mode

View File

@@ -12,7 +12,7 @@ import { OpenAPITags, registry } from "@server/openApi";
import { rebuildClientAssociationsFromSiteResource } from "@server/lib/rebuildClientAssociations"; import { rebuildClientAssociationsFromSiteResource } from "@server/lib/rebuildClientAssociations";
const deleteSiteResourceParamsSchema = z.strictObject({ const deleteSiteResourceParamsSchema = z.strictObject({
siteResourceId: z.string().transform(Number).pipe(z.int().positive()) siteResourceId: z.coerce.number().int().positive()
}); });
export type DeleteSiteResourceResponse = { export type DeleteSiteResourceResponse = {

View File

@@ -11,7 +11,7 @@ import logger from "@server/logger";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const listSiteResourcesParamsSchema = z.strictObject({ const listSiteResourcesParamsSchema = z.strictObject({
siteId: z.string().transform(Number).pipe(z.int().positive()), siteId: z.coerce.number().int().positive(),
orgId: z.string() orgId: z.string()
}); });

View File

@@ -37,7 +37,7 @@ import { z } from "zod";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
const updateSiteResourceParamsSchema = z.strictObject({ const updateSiteResourceParamsSchema = z.strictObject({
siteResourceId: z.string().transform(Number).pipe(z.int().positive()) siteResourceId: z.coerce.number().int().positive()
}); });
const updateSiteResourceSchema = z const updateSiteResourceSchema = z
@@ -58,7 +58,12 @@ const updateSiteResourceSchema = z
// mode: z.enum(["host", "cidr", "port"]).optional(), // mode: z.enum(["host", "cidr", "port"]).optional(),
mode: z.enum(["host", "cidr", "http"]).optional(), mode: z.enum(["host", "cidr", "http"]).optional(),
ssl: z.boolean().optional(), ssl: z.boolean().optional(),
scheme: z.enum(["http", "https"]).nullish(), scheme: z.enum(["http", "https"]).nullish()
.openapi({
description:
"Fully qualified domain name with optional wildcards, e.g., example.internal, *.example.internal, or host-0?.example.internal",
example: "service.example.internal"
}),
// proxyPort: z.int().positive().nullish(), // proxyPort: z.int().positive().nullish(),
destinationPort: z.int().positive().nullish(), destinationPort: z.int().positive().nullish(),
destination: z.string().min(1).optional(), destination: z.string().min(1).optional(),

View File

@@ -26,7 +26,7 @@ import {
} from "@server/lib/alerts"; } from "@server/lib/alerts";
const createTargetParamsSchema = z.strictObject({ const createTargetParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
const createTargetSchema = z.strictObject({ const createTargetSchema = z.strictObject({

View File

@@ -13,7 +13,7 @@ import { OpenAPITags, registry } from "@server/openApi";
import { targetHealthCheck } from "@server/db"; import { targetHealthCheck } from "@server/db";
const deleteTargetSchema = z.strictObject({ const deleteTargetSchema = z.strictObject({
targetId: z.string().transform(Number).pipe(z.int().positive()) targetId: z.coerce.number().int().positive()
}); });
registry.registerPath({ registry.registerPath({

View File

@@ -11,7 +11,7 @@ import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const getTargetSchema = z.strictObject({ const getTargetSchema = z.strictObject({
targetId: z.string().transform(Number).pipe(z.int().positive()) targetId: z.coerce.number().int().positive()
}); });
type GetTargetResponse = Target & type GetTargetResponse = Target &

View File

@@ -11,7 +11,7 @@ import logger from "@server/logger";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const listTargetsParamsSchema = z.strictObject({ const listTargetsParamsSchema = z.strictObject({
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
const listTargetsSchema = z.object({ const listTargetsSchema = z.object({

View File

@@ -20,7 +20,7 @@ import { isTargetValid } from "@server/lib/validators";
import { OpenAPITags, registry } from "@server/openApi"; import { OpenAPITags, registry } from "@server/openApi";
const updateTargetParamsSchema = z.strictObject({ const updateTargetParamsSchema = z.strictObject({
targetId: z.string().transform(Number).pipe(z.int().positive()) targetId: z.coerce.number().int().positive()
}); });
const updateTargetBodySchema = z const updateTargetBodySchema = z

View File

@@ -14,7 +14,7 @@ import { rebuildClientAssociationsFromClient } from "@server/lib/rebuildClientAs
/** Legacy path param order: /role/:roleId/add/:userId */ /** Legacy path param order: /role/:roleId/add/:userId */
const addUserRoleLegacyParamsSchema = z.strictObject({ const addUserRoleLegacyParamsSchema = z.strictObject({
roleId: z.string().transform(stoi).pipe(z.number()), roleId: z.coerce.number(),
userId: z.string() userId: z.string()
}); });

View File

@@ -11,7 +11,7 @@ import { fromError } from "zod-validation-error";
const addUserSiteSchema = z.strictObject({ const addUserSiteSchema = z.strictObject({
userId: z.string(), userId: z.string(),
siteId: z.string().transform(Number).pipe(z.int().positive()) siteId: z.coerce.number().int().positive()
}); });
export async function addUserSite( export async function addUserSite(

View File

@@ -11,7 +11,7 @@ import { fromError } from "zod-validation-error";
const removeUserResourceSchema = z.strictObject({ const removeUserResourceSchema = z.strictObject({
userId: z.string(), userId: z.string(),
resourceId: z.string().transform(Number).pipe(z.int().positive()) resourceId: z.coerce.number().int().positive()
}); });
export async function removeUserResource( export async function removeUserResource(