New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@tsed/platform-response-filter

Package Overview
Dependencies
Maintainers
1
Versions
560
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tsed/platform-response-filter - npm Package Compare versions

Comparing version 8.3.6 to 8.4.0

1

lib/esm/index.js

@@ -12,3 +12,2 @@ /**

export * from "./services/PlatformResponseFilter.js";
export * from "./utils/renderView.js";
//# sourceMappingURL=index.js.map

78

lib/esm/services/PlatformResponseFilter.js
import { isSerializable } from "@tsed/core";
import { constant, inject, injectable } from "@tsed/di";
import { serialize } from "@tsed/json-mapper";
import { renderView } from "../utils/renderView.js";
import { TemplateRenderError } from "../errors/TemplateRenderError.js";
import { PLATFORM_CONTENT_TYPE_RESOLVER } from "./PlatformContentTypeResolver.js";
import { PLATFORM_CONTENT_TYPES_CONTAINER } from "./PlatformContentTypesContainer.js";
/**
* PlatformResponseFilter is responsible for transforming the response data
* to the appropriate format based on the endpoint metadata and context.
*
* @platform

@@ -17,19 +20,35 @@ */

/**
* Call filters to transform data
* @param data
* @param ctx
* Transform the data to the right format.
* @param data The data to transform.
* @param $ctx The context.
*/
transform(data, ctx) {
const { response } = ctx;
if (ctx.endpoint?.operation) {
const bestContentType = this.contentTypeResolver(data, ctx);
bestContentType && response.contentType(bestContentType);
const resolved = this.container.resolve(bestContentType);
if (resolved) {
return resolved.transform(data, ctx);
async transform(data, $ctx) {
const { endpoint } = $ctx;
if (endpoint) {
if (endpoint.view) {
data = await this.renderView(data, $ctx);
}
else if (isSerializable(data)) {
data = await this.serialize(data, $ctx);
}
}
return data;
return this.resolve(data, $ctx);
}
/**
* Render the view with the given data.
* @param data The data to render.
* @param $ctx The context.
* @protected
*/
async renderView(data, $ctx) {
const { response, endpoint } = $ctx;
try {
const { path, options } = endpoint.view;
return await response.render(path, { ...options, ...data, $ctx });
}
catch (err) {
throw new TemplateRenderError(endpoint.targetName, endpoint.propertyKey, err);
}
}
/**
* Serialize data before calling filters

@@ -41,17 +60,22 @@ * @param data

const { response, endpoint } = ctx;
if (endpoint) {
if (endpoint.view) {
data = await renderView(data, ctx);
const responseOpts = endpoint.getResponseOptions(response.statusCode, {
includes: this.getIncludes(ctx)
});
data = serialize(data, {
useAlias: true,
additionalProperties: this.additionalProperties,
...responseOpts,
endpoint: true
});
return data;
}
resolve(data, ctx) {
const { response } = ctx;
if (ctx.endpoint?.operation) {
const bestContentType = this.contentTypeResolver(data, ctx);
bestContentType && response.contentType(bestContentType);
const resolved = this.container.resolve(bestContentType);
if (resolved) {
return resolved.transform(data, ctx);
}
else if (isSerializable(data)) {
const responseOpts = endpoint.getResponseOptions(response.statusCode, {
includes: this.getIncludes(ctx)
});
data = serialize(data, {
useAlias: true,
additionalProperties: this.additionalProperties,
...responseOpts,
endpoint: true
});
}
}

@@ -58,0 +82,0 @@ return data;

@@ -12,2 +12,1 @@ /**

export * from "./services/PlatformResponseFilter.js";
export * from "./utils/renderView.js";
import { BaseContext } from "@tsed/di";
/**
* PlatformResponseFilter is responsible for transforming the response data
* to the appropriate format based on the endpoint metadata and context.
*
* @platform

@@ -13,8 +16,15 @@ */

/**
* Call filters to transform data
* @param data
* @param ctx
* Transform the data to the right format.
* @param data The data to transform.
* @param $ctx The context.
*/
transform(data: unknown, ctx: BaseContext): any;
transform(data: unknown, $ctx: BaseContext): Promise<unknown>;
/**
* Render the view with the given data.
* @param data The data to render.
* @param $ctx The context.
* @protected
*/
protected renderView(data: unknown, $ctx: BaseContext): Promise<any>;
/**
* Serialize data before calling filters

@@ -24,4 +34,5 @@ * @param data

*/
serialize(data: unknown, ctx: BaseContext): Promise<unknown>;
private getIncludes;
protected serialize(data: unknown, ctx: BaseContext): Promise<unknown>;
protected resolve(data: any, ctx: BaseContext): any;
protected getIncludes(ctx: BaseContext): string[] | undefined;
}

@@ -5,3 +5,3 @@ {

"type": "module",
"version": "8.3.6",
"version": "8.4.0",
"source": "./src/index.ts",

@@ -30,9 +30,9 @@ "main": "./lib/esm/index.js",

"devDependencies": {
"@tsed/barrels": "8.3.6",
"@tsed/core": "8.3.6",
"@tsed/di": "8.3.6",
"@tsed/exceptions": "8.3.6",
"@tsed/json-mapper": "8.3.6",
"@tsed/schema": "8.3.6",
"@tsed/typescript": "8.3.6",
"@tsed/barrels": "8.4.0",
"@tsed/core": "8.4.0",
"@tsed/di": "8.4.0",
"@tsed/exceptions": "8.4.0",
"@tsed/json-mapper": "8.4.0",
"@tsed/schema": "8.4.0",
"@tsed/typescript": "8.4.0",
"eslint": "9.12.0",

@@ -43,7 +43,7 @@ "typescript": "5.4.5",

"peerDependencies": {
"@tsed/core": "8.3.6",
"@tsed/di": "8.3.6",
"@tsed/exceptions": "8.3.6",
"@tsed/json-mapper": "8.3.6",
"@tsed/schema": "8.3.6"
"@tsed/core": "8.4.0",
"@tsed/di": "8.4.0",
"@tsed/exceptions": "8.4.0",
"@tsed/json-mapper": "8.4.0",
"@tsed/schema": "8.4.0"
},

@@ -50,0 +50,0 @@ "peerDependenciesMeta": {

@@ -12,2 +12,1 @@ /**

export * from "./services/PlatformResponseFilter.js";
export * from "./utils/renderView.js";
import {catchAsyncError} from "@tsed/core";
import {PlatformTest} from "@tsed/platform-http/testing";
import {Context} from "@tsed/platform-params";
import {EndpointMetadata, Get, Returns, View} from "@tsed/schema";
import {EndpointMetadata, Get, Ignore, Property, Returns, View} from "@tsed/schema";

@@ -32,3 +32,3 @@ import {ResponseFilter} from "../decorators/responseFilter.js";

describe("PlatformResponseFilter", () => {
describe("transform()", () => {
describe("transform() with registered filters", () => {
describe("when filter list is given", () => {

@@ -168,3 +168,2 @@ beforeEach(() =>

});
describe("when filter list is not given", () => {

@@ -233,8 +232,4 @@ beforeEach(() =>

});
describe("serialize()", () => {
beforeEach(() =>
PlatformTest.create({
responseFilters: [CustomJsonFilter, AllFilter, ApplicationJsonFilter]
})
);
describe("transform() without registered filters", () => {
beforeEach(() => PlatformTest.create());
afterEach(() => PlatformTest.reset());

@@ -245,3 +240,3 @@ it("should transform value", async () => {

const result = await platformResponseFilter.serialize({test: "test"}, ctx);
const result = await platformResponseFilter.transform({test: "test"}, ctx);

@@ -262,3 +257,3 @@ expect(result).toEqual({test: "test"});

const result = await platformResponseFilter.serialize({test: "test"}, ctx);
const result = await platformResponseFilter.transform({test: "test"}, ctx);

@@ -282,3 +277,3 @@ expect(result).toEqual({test: "test"});

const result = await platformResponseFilter.serialize({test: "test"}, ctx);
const result = await platformResponseFilter.transform({test: "test"}, ctx);

@@ -302,3 +297,3 @@ expect(result).toEqual({test: "test"});

const result = await platformResponseFilter.serialize({test: "test"}, ctx);
const result = await platformResponseFilter.transform({test: "test"}, ctx);

@@ -322,3 +317,3 @@ expect(result).toEqual({test: "test"});

const result = await platformResponseFilter.serialize({test: "test"}, ctx);
const result = await platformResponseFilter.transform({test: "test"}, ctx);

@@ -339,7 +334,60 @@ expect(result).toEqual("template");

const result = await catchAsyncError(() => platformResponseFilter.serialize({test: "test"}, ctx));
const result = await catchAsyncError(() => platformResponseFilter.transform({test: "test"}, ctx));
expect(result?.message).toEqual("Template rendering error: Test.test()\nError: parsing error");
});
it("should render content", async () => {
class Model {
@Property()
data: string;
@Ignore()
test: string;
}
class Test {
@Get("/")
@View("view", {options: "options"})
@Returns(200, Model)
test() {}
}
const platformResponseFilter = PlatformTest.get<PlatformResponseFilter>(PlatformResponseFilter);
const ctx = PlatformTest.createRequestContext();
ctx.endpoint = EndpointMetadata.get(Test, "test");
vi.spyOn(ctx.response, "render").mockResolvedValue("HTML");
ctx.data = {data: "data"};
await platformResponseFilter.transform(ctx.data, ctx);
expect(ctx.response.render).toHaveBeenCalledWith("view", {
$ctx: ctx,
data: "data",
options: "options"
});
});
it("should render content and throw an error", async () => {
class Test {
@Get("/")
@View("view", {options: "options"})
test() {}
}
const platformResponseFilter = PlatformTest.get<PlatformResponseFilter>(PlatformResponseFilter);
const ctx = PlatformTest.createRequestContext();
ctx.endpoint = EndpointMetadata.get(Test, "test");
vi.spyOn(ctx.response, "render").mockRejectedValue(new Error("parser error"));
ctx.data = {data: "data"};
let actualError: any = await catchAsyncError(() => platformResponseFilter.transform(ctx.data, ctx));
expect(actualError.message).toEqual("Template rendering error: Test.test()\nError: parser error");
});
});
});

@@ -5,3 +5,3 @@ import {isSerializable} from "@tsed/core";

import {renderView} from "../utils/renderView.js";
import {TemplateRenderError} from "../errors/TemplateRenderError.js";
import {PLATFORM_CONTENT_TYPE_RESOLVER} from "./PlatformContentTypeResolver.js";

@@ -11,2 +11,5 @@ import {PLATFORM_CONTENT_TYPES_CONTAINER} from "./PlatformContentTypesContainer.js";

/**
* PlatformResponseFilter is responsible for transforming the response data
* to the appropriate format based on the endpoint metadata and context.
*
* @platform

@@ -20,22 +23,35 @@ */

/**
* Call filters to transform data
* @param data
* @param ctx
* Transform the data to the right format.
* @param data The data to transform.
* @param $ctx The context.
*/
transform(data: unknown, ctx: BaseContext) {
const {response} = ctx;
async transform(data: unknown, $ctx: BaseContext): Promise<unknown> {
const {endpoint} = $ctx;
if (ctx.endpoint?.operation) {
const bestContentType = this.contentTypeResolver(data, ctx);
if (endpoint) {
if (endpoint.view) {
data = await this.renderView(data, $ctx);
} else if (isSerializable(data)) {
data = await this.serialize(data, $ctx);
}
}
bestContentType && response.contentType(bestContentType);
return this.resolve(data, $ctx);
}
const resolved = this.container.resolve(bestContentType);
/**
* Render the view with the given data.
* @param data The data to render.
* @param $ctx The context.
* @protected
*/
protected async renderView(data: unknown, $ctx: BaseContext) {
const {response, endpoint} = $ctx;
try {
const {path, options} = endpoint.view;
if (resolved) {
return resolved.transform(data, ctx);
}
return await response.render(path, {...options, ...(data as object), $ctx});
} catch (err) {
throw new TemplateRenderError(endpoint.targetName, endpoint.propertyKey, err);
}
return data;
}

@@ -48,19 +64,31 @@

*/
async serialize(data: unknown, ctx: BaseContext) {
protected async serialize(data: unknown, ctx: BaseContext) {
const {response, endpoint} = ctx;
if (endpoint) {
if (endpoint.view) {
data = await renderView(data, ctx);
} else if (isSerializable(data)) {
const responseOpts = endpoint.getResponseOptions(response.statusCode, {
includes: this.getIncludes(ctx)
});
const responseOpts = endpoint.getResponseOptions(response.statusCode, {
includes: this.getIncludes(ctx)
});
data = serialize(data, {
useAlias: true,
additionalProperties: this.additionalProperties,
...responseOpts,
endpoint: true
});
data = serialize(data, {
useAlias: true,
additionalProperties: this.additionalProperties,
...responseOpts,
endpoint: true
});
return data;
}
protected resolve(data: any, ctx: BaseContext) {
const {response} = ctx;
if (ctx.endpoint?.operation) {
const bestContentType = this.contentTypeResolver(data, ctx);
bestContentType && response.contentType(bestContentType);
const resolved = this.container.resolve(bestContentType);
if (resolved) {
return resolved.transform(data, ctx);
}

@@ -72,3 +100,3 @@ }

private getIncludes(ctx: BaseContext) {
protected getIncludes(ctx: BaseContext) {
if (ctx.request.query.includes) {

@@ -75,0 +103,0 @@ return [].concat(ctx.request.query.includes).flatMap((include: string) => include.split(","));

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc