{"version":3,"sources":["../../server/index.ts"],"sourcesContent":["import express from \"express\";\nimport contentDisposition from \"content-disposition\";\nimport {\n    assertActionMethodBodyContract,\n    assertActionPath,\n    assertFlatScalarQuery,\n    createDTISignPayload,\n    DTI_DEFAULT_SIGN_HEADER_NAMES,\n    DTIError,\n    parseDTISignTimestamp,\n    resolveActionMethod,\n    resolveDTISignHeaderNames,\n    verifyDTIHmacSha256,\n} from \"@napp/dti-core\";\nimport type { ActionParam, ActionResult, DTIAction, DTISignHeaderNames, INonceStore, TContentType, TMethod } from \"@napp/dti-core\";\nimport type { NextFunction, Request, RequestHandler, Response, Router } from \"express\";\nimport type { z } from \"zod\";\n\ntype TActionSchema = z.ZodType;\ntype TAnyAction = DTIAction<any, any, any, any, any>;\ntype InferActionSchema<TSchema> = TSchema extends TActionSchema ? z.infer<TSchema> : void;\ntype DTIServerAuth<AuthContext> = [AuthContext] extends [undefined]\n    ? { auth?: undefined }\n    : { auth: AuthContext };\ntype DTIServerMeta<MetaContext> = [MetaContext] extends [undefined]\n    ? { meta?: undefined }\n    : { meta: MetaContext };\n\nexport type DTIAuthParam<TAction extends TAnyAction = TAnyAction> = {\n    action: TAction;\n    req: Request;\n    res: Response;\n};\n\nexport type DTIAuthVerify<AuthContext> = (\n    param: DTIAuthParam,\n) => AuthContext | Promise<AuthContext>;\n\nexport type DTIMetaParam<AuthContext> = {\n    req: Request;\n    res: Response;\n} & DTIServerAuth<AuthContext>;\n\nexport type DTIMetaResolve<AuthContext, MetaContext> = (\n    param: DTIMetaParam<AuthContext>,\n) => MetaContext | Promise<MetaContext>;\n\nexport type DTIMetaOption<AuthContext, MetaContext> =\n    | MetaContext\n    | DTIMetaResolve<AuthContext, MetaContext>;\n\nexport type DTISignSecretParam = {\n    keyId: string;\n    req: Request;\n    res: Response;\n};\n\nexport type DTISignSecretProvider = (\n    param: DTISignSecretParam,\n) => string | Promise<string>;\n\nexport type DTIServerSignOptions = {\n    getSecret: DTISignSecretProvider;\n    nonceStore: INonceStore;\n    toleranceMs?: number;\n    headerNames?: Partial<DTISignHeaderNames>;\n};\n\nexport type DTIErrorParseParam<TAction extends TAnyAction = TAnyAction> = {\n    error: unknown;\n    action: TAction;\n    req: Request;\n    res: Response;\n};\n\nexport type DTIErrorParser = (\n    param: DTIErrorParseParam,\n) => DTIError | undefined | Promise<DTIError | undefined>;\n\nexport type DTIServerErrorOptions = {\n    parse?: DTIErrorParser;\n};\n\nexport type DTIExpressRouterOptions<AuthContext = undefined, MetaContext = undefined> = {\n    auth?: DTIAuthVerify<AuthContext>;\n    error?: DTIServerErrorOptions;\n    meta?: DTIMetaOption<AuthContext, MetaContext>;\n    sign?: DTIServerSignOptions;\n};\n\nexport type DTIFileBody = Buffer | Uint8Array | ArrayBuffer | Blob | string;\n\nexport type DTITextResponse = {\n    type: \"text\";\n    body: string;\n    contentType?: string;\n    headers?: Record<string, string>;\n    status?: number;\n};\n\nexport type DTITextOptions = {\n    contentType?: string;\n    headers?: Record<string, string>;\n    status?: number;\n};\n\nexport type DTIFileResponse = {\n    type: \"file\";\n    body: DTIFileBody;\n    filename?: string;\n    contentType?: string;\n    headers?: Record<string, string>;\n    status?: number;\n};\n\nexport type DTIFileOptions = {\n    body: DTIFileBody;\n    filename?: string;\n    contentType?: string;\n    headers?: Record<string, string>;\n    status?: number;\n};\n\nexport type DTIServerParam<TAction extends TAnyAction, AuthContext = undefined, MetaContext = undefined> =\n    TAction extends DTIAction<infer _RSchema, infer QSchema, infer BSchema, infer _ResponseType, infer PSchema>\n    ? ActionParam<InferActionSchema<QSchema>, InferActionSchema<BSchema>, InferActionSchema<PSchema>> & {\n        req: Request;\n        res: Response;\n    } & DTIServerAuth<AuthContext>\n    & DTIServerMeta<MetaContext>\n    : never;\n\nexport type DTIServerResult<TAction extends TAnyAction> =\n    TAction extends DTIAction<infer RSchema, infer _QSchema, infer _BSchema, infer ResponseType, infer _PSchema>\n    ? ResponseType extends \"text\"\n    ? string | DTITextResponse\n    : ResponseType extends \"file\"\n    ? DTIFileResponse\n    : InferActionSchema<RSchema>\n    : never;\n\nexport type DTIActionHandler<TAction extends TAnyAction, AuthContext = undefined, MetaContext = undefined> = (\n    param: DTIServerParam<TAction, AuthContext, MetaContext>,\n) => DTIServerResult<TAction> | Promise<DTIServerResult<TAction>>;\n\ntype TSuccessResponse = {\n    success: true;\n    data: unknown;\n};\n\ntype TFailureResponse = {\n    success: false;\n    code: string;\n    message: string;\n    details?: Record<string, unknown>;\n};\n\ntype TDTIResponse = TSuccessResponse | TFailureResponse;\n\nexport function dtiText(body: string, options?: DTITextOptions): DTITextResponse {\n    return {\n        type: \"text\",\n        body,\n        ...options,\n    };\n}\n\nexport function dtiFile(response: DTIFileOptions): DTIFileResponse {\n    return {\n        type: \"file\",\n        ...response,\n    };\n}\n\nexport class DTIExpressRouter<AuthContext = undefined, MetaContext = undefined> {\n    private readonly expressRouter = express.Router();\n    private readonly actionNames = new Map<string, string>();\n    private readonly routeKeys = new Map<string, string>();\n    private readonly signHeaderNames: Readonly<DTISignHeaderNames>;\n    private readonly signToleranceMs: number;\n\n    constructor(private readonly options: DTIExpressRouterOptions<AuthContext, MetaContext> = {}) {\n        this.signHeaderNames = options.sign\n            ? resolveDTISignHeaderNames(options.sign.headerNames)\n            : DTI_DEFAULT_SIGN_HEADER_NAMES;\n        this.signToleranceMs = this.resolveSignTolerance(options.sign?.toleranceMs);\n    }\n\n    action<TAction extends TAnyAction>(action: TAction, handler: DTIActionHandler<TAction, AuthContext, MetaContext>): this {\n        assertActionPath(action.path);\n        assertActionMethodBodyContract(action.method, action.body);\n        const path = action.path;\n        const method = resolveActionMethod(action);\n        const contentType = action.contentType || \"json\";\n        const routeHandler = this.createRouteHandler(action, handler);\n\n        this.assertUniqueAction(action, method, path);\n        this.registerRoute(method, path, method === \"GET\"\n            ? [routeHandler]\n            : [this.createBodyParser(contentType), routeHandler]);\n\n        return this;\n    }\n\n    router(): Router {\n        return this.expressRouter;\n    }\n\n    private createRouteHandler<TAction extends TAnyAction>(\n        action: TAction,\n        handler: DTIActionHandler<TAction, AuthContext, MetaContext>,\n    ): RequestHandler {\n        return async (req, res, next) => {\n            try {\n                const param = await this.parseParam(action, req, res);\n\n                if (action.validateParam && !action.validateParam(param)) {\n                    throw new DTIError(\"Invalid action param\", { code: \"DTI_PARAM_VALIDATE_ERROR\" });\n                }\n\n                const result = await handler(param);\n                const responseType = action.responseType || \"json\";\n\n                if (responseType === \"text\") {\n                    const textResponse = this.parseTextResult(result);\n                    if (action.validateResult && !this.validateResult(action.validateResult, textResponse.body)) {\n                        throw new DTIError(\"Invalid action result\", { code: \"DTI_RESULT_VALIDATE_ERROR\" });\n                    }\n                    this.sendTextResponse(res, textResponse);\n                    return;\n                }\n\n                if (responseType === \"file\") {\n                    const fileResponse = this.parseFileResult(result);\n                    if (action.validateResult) {\n                        const blob = await this.createFileBlob(fileResponse);\n                        if (!this.validateResult(action.validateResult, blob)) {\n                            throw new DTIError(\"Invalid action result\", { code: \"DTI_RESULT_VALIDATE_ERROR\" });\n                        }\n                    }\n                    await this.sendFileResponse(res, fileResponse);\n                    return;\n                }\n\n                const validResult = this.parseJsonResult(action, result);\n\n                if (action.validateResult && !this.validateResult(action.validateResult, validResult)) {\n                    throw new DTIError(\"Invalid action result\", { code: \"DTI_RESULT_VALIDATE_ERROR\" });\n                }\n\n                if (this.isBodylessStatus(res.statusCode)) {\n                    res.end();\n                    return;\n                }\n\n                res.json(this.createSuccessResponse(validResult));\n            } catch (error) {\n                await this.handleError(error, action, req, res, next);\n            }\n        };\n    }\n\n    private async parseParam<TAction extends TAnyAction>(\n        action: TAction,\n        req: Request,\n        res: Response,\n    ): Promise<DTIServerParam<TAction, AuthContext, MetaContext>> {\n        const param = {\n            req,\n            res,\n        } as DTIServerParam<TAction, AuthContext, MetaContext>;\n\n        if (action.params) {\n            const parsedPathParams = action.params.safeParse(req.params);\n            if (!parsedPathParams.success) {\n                throw new DTIError(\"Invalid action path params\", { code: \"DTI_PATH_PARAMS_VALIDATE_ERROR\" });\n            }\n            param.params = parsedPathParams.data;\n        }\n\n        if (action.query) {\n            assertFlatScalarQuery(req.query);\n            const parsedQuery = action.query.safeParse(req.query);\n            if (!parsedQuery.success) {\n                throw new DTIError(\"Invalid action query\", { code: \"DTI_QUERY_VALIDATE_ERROR\" });\n            }\n            assertFlatScalarQuery(parsedQuery.data);\n            param.query = parsedQuery.data;\n        }\n\n        if (action.body) {\n            const parsedBody = action.body.safeParse(req.body);\n            if (!parsedBody.success) {\n                throw new DTIError(\"Invalid action body\", { code: \"DTI_BODY_VALIDATE_ERROR\" });\n            }\n            param.body = parsedBody.data;\n        }\n\n        await this.verifySignature(action, param, req, res);\n\n        const auth = await this.verifyAuth(action, req, res);\n        if (this.options.auth) {\n            Object.assign(param, { auth });\n        }\n\n        const meta = await this.resolveMeta(req, res, auth);\n        if (this.options.meta !== undefined) {\n            Object.assign(param, { meta });\n        }\n\n        return param;\n    }\n\n    private async verifySignature<TAction extends TAnyAction>(\n        action: TAction,\n        param: DTIServerParam<TAction, AuthContext, MetaContext>,\n        req: Request,\n        res: Response,\n    ): Promise<void> {\n        const sign = this.options.sign;\n        if (!sign) {\n            return;\n        }\n\n        if (!action.signature) {\n            throw new DTIError(\"Action signature is required\", { code: \"DTI_SIGNATURE_REQUIRED\", status: 401 });\n        }\n\n        const keyId = this.getRequiredSignHeader(req, this.signHeaderNames.keyId);\n        const timestamp = this.getRequiredSignHeader(req, this.signHeaderNames.timestamp);\n        const nonce = this.getRequiredSignHeader(req, this.signHeaderNames.nonce);\n        const signature = this.getRequiredSignHeader(req, this.signHeaderNames.signature);\n        const toleranceMs = this.signToleranceMs;\n\n        const timestampMs = this.validateSignTimestamp(timestamp, toleranceMs);\n\n        const actionSignature = action.signature(param);\n        const signPayload = createDTISignPayload({\n            method: resolveActionMethod(action),\n            pathWithQuery: req.url,\n            timestamp,\n            nonce,\n            actionSignature,\n        });\n        const secret = await sign.getSecret({\n            keyId,\n            req,\n            res,\n        });\n\n        if (!await verifyDTIHmacSha256(secret, signPayload, signature)) {\n            throw new DTIError(\"Invalid request signature\", { code: \"DTI_SIGNATURE_INVALID\", status: 401 });\n        }\n\n        const nonceKey = this.createNonceKey(keyId, nonce);\n        const nonceTtlMs = Math.max(1, timestampMs + toleranceMs - Date.now());\n        if (!await sign.nonceStore.consume(nonceKey, nonceTtlMs)) {\n            throw new DTIError(\"Request nonce already used\", { code: \"DTI_REPLAY_DETECTED\", status: 401 });\n        }\n    }\n\n    private getRequiredSignHeader(req: Request, name: string): string {\n        const value = req.header(name);\n        if (!value) {\n            throw new DTIError(\"Request signature is required\", { code: \"DTI_SIGNATURE_REQUIRED\", status: 401 });\n        }\n\n        return value;\n    }\n\n    private validateSignTimestamp(timestamp: string, toleranceMs: number): number {\n        const timestampMs = parseDTISignTimestamp(timestamp);\n        if (timestampMs === undefined || Math.abs(Date.now() - timestampMs) > toleranceMs) {\n            throw new DTIError(\"Request signature timestamp is invalid\", { code: \"DTI_SIGNATURE_TIMESTAMP_INVALID\", status: 401 });\n        }\n\n        return timestampMs;\n    }\n\n    private resolveSignTolerance(toleranceMs: number | undefined): number {\n        const resolvedToleranceMs = toleranceMs ?? 5 * 60 * 1000;\n        if (!Number.isSafeInteger(resolvedToleranceMs) || resolvedToleranceMs <= 0) {\n            throw new DTIError(\"Invalid DTI signing configuration\", {\n                code: \"DTI_SIGN_CONFIG_ERROR\",\n                details: {\n                    field: \"toleranceMs\",\n                    reason: \"toleranceMs must be a positive safe integer\",\n                },\n            });\n        }\n\n        return resolvedToleranceMs;\n    }\n\n    private createNonceKey(keyId: string, nonce: string): string {\n        return `${keyId}:${nonce}`;\n    }\n\n    private async verifyAuth<TAction extends TAnyAction>(\n        action: TAction,\n        req: Request,\n        res: Response,\n    ): Promise<AuthContext | undefined> {\n        if (!this.options.auth) {\n            return undefined;\n        }\n\n        return await this.options.auth({ action, req, res });\n    }\n\n    private async resolveMeta(req: Request, res: Response, auth: AuthContext | undefined): Promise<MetaContext | undefined> {\n        const meta = this.options.meta;\n        if (meta === undefined) {\n            return undefined;\n        }\n\n        if (typeof meta === \"function\") {\n            const metaParam = {\n                req,\n                res,\n            } as DTIMetaParam<AuthContext>;\n\n            if (this.options.auth) {\n                Object.assign(metaParam, { auth });\n            }\n\n            return await (meta as DTIMetaResolve<AuthContext, MetaContext>)(metaParam);\n        }\n\n        return meta;\n    }\n\n    private parseJsonResult<TAction extends TAnyAction>(\n        action: TAction,\n        result: DTIServerResult<TAction>,\n    ): DTIServerResult<TAction> {\n        if (!action.result) {\n            return undefined as DTIServerResult<TAction>;\n        }\n\n        const parsedResult = action.result.safeParse(result);\n        if (!parsedResult.success) {\n            throw new DTIError(\"Invalid action result\", { code: \"DTI_RESULT_PARSE_ERROR\" });\n        }\n\n        return parsedResult.data as DTIServerResult<TAction>;\n    }\n\n    private parseTextResult(result: unknown): DTITextResponse {\n        if (this.isTextResponse(result)) {\n            return result;\n        }\n\n        if (typeof result !== \"string\") {\n            throw new DTIError(\"Invalid text result\", { code: \"DTI_RESULT_PARSE_ERROR\" });\n        }\n\n        return dtiText(result);\n    }\n\n    private parseFileResult(result: unknown): DTIFileResponse {\n        if (!this.isFileResponse(result)) {\n            throw new DTIError(\"Invalid file result\", { code: \"DTI_RESULT_PARSE_ERROR\" });\n        }\n\n        return result;\n    }\n\n    private validateResult<TResult>(\n        validate: (param: ActionResult<TResult>) => boolean,\n        result: TResult,\n    ): boolean {\n        return validate({ result } as ActionResult<TResult>);\n    }\n\n    private registerRoute(method: TMethod, path: string, handlers: RequestHandler[]): void {\n        switch (method) {\n            case \"GET\":\n                this.expressRouter.get(path, ...handlers);\n                return;\n            case \"PUT\":\n                this.expressRouter.put(path, ...handlers);\n                return;\n            case \"DELETE\":\n                this.expressRouter.delete(path, ...handlers);\n                return;\n            case \"PATCH\":\n                this.expressRouter.patch(path, ...handlers);\n                return;\n            case \"POST\":\n            default:\n                this.expressRouter.post(path, ...handlers);\n        }\n    }\n\n    private assertUniqueAction(action: TAnyAction, method: TMethod, path: string): void {\n        const existingNameRoute = this.actionNames.get(action.name);\n        if (existingNameRoute) {\n            throw new DTIError(\"Duplicate DTI action name\", {\n                code: \"DTI_ACTION_NAME_DUPLICATE\",\n                details: {\n                    name: action.name,\n                    existingRoute: existingNameRoute,\n                    route: this.createRouteKey(method, path),\n                },\n            });\n        }\n\n        const routeKey = this.createRouteKey(method, path);\n        const existingRouteAction = this.routeKeys.get(routeKey);\n        if (existingRouteAction) {\n            throw new DTIError(\"Duplicate DTI action route\", {\n                code: \"DTI_ACTION_ROUTE_DUPLICATE\",\n                details: {\n                    route: routeKey,\n                    existingActionName: existingRouteAction,\n                    actionName: action.name,\n                },\n            });\n        }\n\n        this.actionNames.set(action.name, routeKey);\n        this.routeKeys.set(routeKey, action.name);\n    }\n\n    private createRouteKey(method: TMethod, path: string): string {\n        return `${method} ${this.normalizeRoutePath(path)}`;\n    }\n\n    private normalizeRoutePath(path: string): string {\n        if (path.length > 1 && path.endsWith(\"/\")) {\n            return path.slice(0, -1);\n        }\n\n        return path;\n    }\n\n    private createBodyParser(contentType: TContentType): RequestHandler {\n        switch (contentType) {\n            case \"form\":\n                return express.urlencoded({ extended: true });\n            case \"text\":\n                return express.text();\n            case \"json\":\n            default:\n                return express.json();\n        }\n    }\n\n    private sendTextResponse(res: Response, response: DTITextResponse): void {\n        this.setHeaders(res, response.headers);\n        if (response.status !== undefined) {\n            res.status(response.status);\n        }\n        res.setHeader(\"Content-Type\", response.contentType || \"text/plain; charset=utf-8\");\n        if (this.isBodylessStatus(res.statusCode)) {\n            res.end();\n            return;\n        }\n        res.end(response.body);\n    }\n\n    private async sendFileResponse(res: Response, response: DTIFileResponse): Promise<void> {\n        const disposition = response.filename === undefined\n            ? undefined\n            : this.createContentDisposition(response.filename);\n        this.setHeaders(res, response.headers);\n        if (response.status !== undefined) {\n            res.status(response.status);\n        }\n\n        const contentType = response.contentType || \"application/octet-stream\";\n        res.setHeader(\"Content-Type\", contentType);\n\n        if (disposition !== undefined) {\n            res.setHeader(\"Content-Disposition\", disposition);\n        }\n\n        if (this.isBodylessStatus(res.statusCode)) {\n            res.end();\n            return;\n        }\n\n        res.send(await this.normalizeFileBody(response.body));\n    }\n\n    private setHeaders(res: Response, headers?: Record<string, string>): void {\n        if (!headers) {\n            return;\n        }\n\n        for (const [key, value] of Object.entries(headers)) {\n            res.setHeader(key, value);\n        }\n    }\n\n    private createSuccessResponse(data: unknown): TDTIResponse {\n        return {\n            success: true,\n            data,\n        };\n    }\n\n    private createFailureResponse(error: DTIError): TDTIResponse {\n        const response: TFailureResponse = {\n            success: false,\n            code: error.code || \"DTI_ERROR\",\n            message: error.message,\n        };\n\n        if (error.details) {\n            response.details = error.details;\n        }\n\n        return response;\n    }\n\n    private async handleError<TAction extends TAnyAction>(\n        error: unknown,\n        action: TAction,\n        req: Request,\n        res: Response,\n        next: NextFunction,\n    ): Promise<void> {\n        if (res.headersSent) {\n            next(error);\n            return;\n        }\n\n        const parsedError = await this.parseError(error, action, req, res);\n        if (parsedError) {\n            res.status(this.getErrorStatus(parsedError)).json(this.createFailureResponse(parsedError));\n            return;\n        }\n\n        res.status(500).json(this.createFailureResponse(new DTIError(\"Internal server error\", { code: \"DTI_INTERNAL_ERROR\" })));\n    }\n\n    private async parseError<TAction extends TAnyAction>(\n        error: unknown,\n        action: TAction,\n        req: Request,\n        res: Response,\n    ): Promise<DTIError | undefined> {\n        if (error instanceof DTIError) {\n            return error;\n        }\n\n        const parser = this.options.error?.parse;\n        if (!parser) {\n            return undefined;\n        }\n\n        try {\n            const parsedError = await parser({\n                error,\n                action,\n                req,\n                res,\n            });\n\n            return parsedError instanceof DTIError ? parsedError : undefined;\n        } catch (parserError) {\n            return parserError instanceof DTIError ? parserError : undefined;\n        }\n    }\n\n    private getErrorStatus(error: DTIError): number {\n        if (error.status) {\n            return error.status;\n        }\n\n        switch (error.code) {\n            case \"AUTH_REQUIRED\":\n            case \"INVALID_TOKEN\":\n            case \"DTI_SIGNATURE_REQUIRED\":\n            case \"DTI_SIGNATURE_TIMESTAMP_INVALID\":\n            case \"DTI_SIGNATURE_INVALID\":\n            case \"DTI_REPLAY_DETECTED\":\n                return 401;\n            case \"PERMISSION_DENIED\":\n                return 403;\n            case \"DTI_PATH_PARAMS_VALIDATE_ERROR\":\n            case \"DTI_QUERY_VALIDATE_ERROR\":\n            case \"DTI_BODY_VALIDATE_ERROR\":\n            case \"DTI_PARAM_VALIDATE_ERROR\":\n                return 400;\n            case \"DTI_RESULT_PARSE_ERROR\":\n            case \"DTI_RESULT_VALIDATE_ERROR\":\n                return 500;\n            default:\n                return 500;\n        }\n    }\n\n    private isTextResponse(result: unknown): result is DTITextResponse {\n        return !!result && typeof result === \"object\" && \"type\" in result && result.type === \"text\";\n    }\n\n    private isFileResponse(result: unknown): result is DTIFileResponse {\n        return !!result && typeof result === \"object\" && \"type\" in result && result.type === \"file\" && \"body\" in result;\n    }\n\n    private async createFileBlob(response: DTIFileResponse): Promise<Blob> {\n        if (this.isBlob(response.body)) {\n            return response.body;\n        }\n\n        const body = await this.normalizeFileBody(response.body);\n\n        return new Blob([new Uint8Array(body)], {\n            type: response.contentType || \"application/octet-stream\",\n        });\n    }\n\n    private async normalizeFileBody(body: DTIFileBody): Promise<Buffer> {\n        if (typeof body === \"string\") {\n            return Buffer.from(body);\n        }\n\n        if (this.isBlob(body)) {\n            return Buffer.from(await body.arrayBuffer());\n        }\n\n        if (body instanceof ArrayBuffer) {\n            return Buffer.from(body);\n        }\n\n        return Buffer.from(body.buffer, body.byteOffset, body.byteLength);\n    }\n\n    private isBlob(value: unknown): value is Blob {\n        return typeof Blob !== \"undefined\" && value instanceof Blob;\n    }\n\n    private createContentDisposition(filename: string): string {\n        if (typeof filename !== \"string\" || filename.length === 0) {\n            throw new DTIError(\"Invalid file response filename\", { code: \"DTI_FILE_NAME_ERROR\" });\n        }\n\n        const normalizedFilename = filename.normalize(\"NFC\");\n        if (normalizedFilename === \".\"\n            || normalizedFilename === \"..\"\n            || /[\\\\/]/.test(normalizedFilename)\n            || /[\\x00-\\x1F\\x7F]/.test(normalizedFilename)) {\n            throw new DTIError(\"Invalid file response filename\", { code: \"DTI_FILE_NAME_ERROR\" });\n        }\n\n        const asciiFallback = this.createAsciiFilenameFallback(normalizedFilename);\n        return contentDisposition(normalizedFilename, {\n            type: \"attachment\",\n            fallback: asciiFallback,\n        });\n    }\n\n    private createAsciiFilenameFallback(filename: string): string {\n        const fallback = filename.replace(/[^A-Za-z0-9._ -]/g, \"_\");\n        return fallback.trim().length > 0 ? fallback : \"download\";\n    }\n\n    private isBodylessStatus(status: number): boolean {\n        return status === 204 || status === 205;\n    }\n}\n\nexport function createDTIExpressRouter<AuthContext = undefined, MetaContext = undefined>(\n    options?: DTIExpressRouterOptions<AuthContext, MetaContext>,\n): DTIExpressRouter<AuthContext, MetaContext> {\n    return new DTIExpressRouter(options);\n}\n"],"mappings":"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","names":["express","contentDisposition"]}