@tsed/platform-response-filter 7.0.0-alpha.2 → 7.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/lib/cjs/decorators/responseFilter.js +23 -0
  2. package/lib/cjs/decorators/responseFilter.js.map +1 -0
  3. package/lib/cjs/domain/ResponseFiltersContainer.js +16 -0
  4. package/lib/cjs/domain/ResponseFiltersContainer.js.map +1 -0
  5. package/lib/cjs/errors/TemplateRenderError.js +23 -0
  6. package/lib/cjs/errors/TemplateRenderError.js.map +1 -0
  7. package/lib/cjs/index.js +15 -0
  8. package/lib/cjs/index.js.map +1 -0
  9. package/lib/cjs/interfaces/ResponseFilterMethods.js +3 -0
  10. package/lib/cjs/interfaces/ResponseFilterMethods.js.map +1 -0
  11. package/lib/cjs/services/PlatformResponseFilter.js +94 -0
  12. package/lib/cjs/services/PlatformResponseFilter.js.map +1 -0
  13. package/lib/cjs/utils/getContentType.js +28 -0
  14. package/lib/cjs/utils/getContentType.js.map +1 -0
  15. package/lib/cjs/utils/renderView.js +17 -0
  16. package/lib/cjs/utils/renderView.js.map +1 -0
  17. package/lib/esm/decorators/responseFilter.js +19 -0
  18. package/lib/esm/decorators/responseFilter.js.map +1 -0
  19. package/lib/esm/domain/ResponseFiltersContainer.js +12 -0
  20. package/lib/esm/domain/ResponseFiltersContainer.js.map +1 -0
  21. package/lib/esm/errors/TemplateRenderError.js +19 -0
  22. package/lib/esm/errors/TemplateRenderError.js.map +1 -0
  23. package/lib/esm/index.js +12 -0
  24. package/lib/esm/index.js.map +1 -0
  25. package/lib/esm/interfaces/ResponseFilterMethods.js +2 -0
  26. package/lib/esm/interfaces/ResponseFilterMethods.js.map +1 -0
  27. package/lib/esm/services/PlatformResponseFilter.js +91 -0
  28. package/lib/esm/services/PlatformResponseFilter.js.map +1 -0
  29. package/lib/esm/utils/getContentType.js +24 -0
  30. package/lib/esm/utils/getContentType.js.map +1 -0
  31. package/lib/esm/utils/renderView.js +13 -0
  32. package/lib/esm/utils/renderView.js.map +1 -0
  33. package/lib/{decorators → types/decorators}/responseFilter.d.ts +0 -0
  34. package/lib/{domain → types/domain}/ResponseFiltersContainer.d.ts +0 -0
  35. package/lib/types/errors/TemplateRenderError.d.ts +14 -0
  36. package/lib/{index.d.ts → types/index.d.ts} +2 -0
  37. package/lib/{interfaces → types/interfaces}/ResponseFilterMethods.d.ts +0 -0
  38. package/lib/{services → types/services}/PlatformResponseFilter.d.ts +1 -1
  39. package/lib/{utils → types/utils}/getContentType.d.ts +0 -0
  40. package/lib/types/utils/renderView.d.ts +2 -0
  41. package/package.json +23 -20
  42. package/tsconfig.compile.esm.json +23 -0
  43. package/lib/index.js +0 -566
  44. package/lib/index.js.map +0 -1
  45. package/lib/index.modern.js +0 -562
  46. package/lib/index.modern.js.map +0 -1
package/package.json CHANGED
@@ -1,34 +1,40 @@
1
1
  {
2
2
  "name": "@tsed/platform-response-filter",
3
- "version": "7.0.0-alpha.2",
3
+ "version": "7.0.0-beta.1",
4
4
  "description": "Platform response filter module for Ts.ED Framework",
5
5
  "private": false,
6
6
  "source": "./src/index.ts",
7
- "main": "./lib/index.js",
8
- "typings": "./lib/index.d.ts",
7
+ "main": "./lib/cjs/index.js",
8
+ "typings": "./lib/types/index.d.ts",
9
9
  "exports": {
10
- "require": "./lib/index.js",
11
- "default": "./lib/index.modern.js"
10
+ "types": "./lib/types/index.d.ts",
11
+ "import": "./lib/esm/index.js",
12
+ "require": "./lib/cjs/index.js",
13
+ "default": "./lib/esm/index.js"
12
14
  },
13
15
  "scripts": {
14
- "build": "microbundle --target node --no-compress --format modern,cjs --tsconfig ./tsconfig.compile.json"
16
+ "build": "yarn run build:esm && yarn run build:cjs",
17
+ "build:cjs": "tsc --build tsconfig.compile.json",
18
+ "build:esm": "tsc --build tsconfig.compile.esm.json"
15
19
  },
16
20
  "dependencies": {
17
21
  "tslib": "2.2.0"
18
22
  },
19
23
  "devDependencies": {
20
- "@tsed/core": "7.0.0-alpha.2",
21
- "@tsed/di": "7.0.0-alpha.2",
22
- "@tsed/exceptions": "7.0.0-alpha.2",
23
- "@tsed/platform-views": "7.0.0-alpha.2",
24
- "@tsed/schema": "7.0.0-alpha.2"
24
+ "@tsed/core": "7.0.0-beta.1",
25
+ "@tsed/di": "7.0.0-beta.1",
26
+ "@tsed/exceptions": "7.0.0-beta.1",
27
+ "@tsed/json-mapper": "7.0.0-beta.1",
28
+ "@tsed/platform-views": "7.0.0-beta.1",
29
+ "@tsed/schema": "7.0.0-beta.1"
25
30
  },
26
31
  "peerDependencies": {
27
- "@tsed/core": "^7.0.0-alpha.2",
28
- "@tsed/di": "^7.0.0-alpha.2",
29
- "@tsed/exceptions": "^7.0.0-alpha.2",
30
- "@tsed/platform-views": "^7.0.0-alpha.2",
31
- "@tsed/schema": "^7.0.0-alpha.2"
32
+ "@tsed/core": "^7.0.0-beta.1",
33
+ "@tsed/di": "^7.0.0-beta.1",
34
+ "@tsed/exceptions": "^7.0.0-beta.1",
35
+ "@tsed/json-mapper": "^7.0.0-beta.1",
36
+ "@tsed/platform-views": "^7.0.0-beta.1",
37
+ "@tsed/schema": "^7.0.0-beta.1"
32
38
  },
33
39
  "repository": "https://github.com/tsedio/tsed",
34
40
  "bugs": {
@@ -36,8 +42,5 @@
36
42
  },
37
43
  "homepage": "https://github.com/tsedio/tsed/tree/alpha/packages/platform/platform-response-filter",
38
44
  "author": "Romain Lenzotti",
39
- "license": "MIT",
40
- "publishConfig": {
41
- "tag": "alpha"
42
- }
45
+ "license": "MIT"
43
46
  }
@@ -0,0 +1,23 @@
1
+ {
2
+ "extends": "./tsconfig.compile.json",
3
+ "compilerOptions": {
4
+ "baseUrl": ".",
5
+ "module": "ES2020",
6
+ "rootDir": "src",
7
+ "outDir": "./lib/esm",
8
+ "declaration": true,
9
+ "declarationDir": "./lib/types"
10
+ },
11
+ "exclude": [
12
+ "node_modules",
13
+ "test",
14
+ "lib",
15
+ "benchmark",
16
+ "coverage",
17
+ "spec",
18
+ "**/*.benchmark.ts",
19
+ "**/*.spec.ts",
20
+ "keys",
21
+ "jest.config.js"
22
+ ]
23
+ }
package/lib/index.js DELETED
@@ -1,566 +0,0 @@
1
- var di = require('@tsed/di');
2
- var tslib = require('tslib');
3
- var core = require('@tsed/core');
4
- var exceptions = require('@tsed/exceptions');
5
- var schema = require('@tsed/schema');
6
- var platformViews = require('@tsed/platform-views');
7
-
8
- /**
9
- * @ignore
10
- */
11
- // tslint:disable-next-line:variable-name
12
- const ResponseFiltersContainer = new Map();
13
- /**
14
- * @ignore
15
- */
16
-
17
- function registerResponseFilter(type, token) {
18
- ResponseFiltersContainer.set(type, token);
19
- }
20
-
21
- /**
22
- * Register a response filter service.
23
- * @param contentTypes
24
- * @decorator
25
- */
26
-
27
- function ResponseFilter(...contentTypes) {
28
- return target => {
29
- contentTypes.forEach(contentType => {
30
- registerResponseFilter(contentType, target);
31
- });
32
- di.registerProvider({
33
- provide: target,
34
- useClass: target
35
- });
36
- };
37
- }
38
-
39
- function _extends$1() {
40
- _extends$1 = Object.assign || function (target) {
41
- for (var i = 1; i < arguments.length; i++) {
42
- var source = arguments[i];
43
-
44
- for (var key in source) {
45
- if (Object.prototype.hasOwnProperty.call(source, key)) {
46
- target[key] = source[key];
47
- }
48
- }
49
- }
50
-
51
- return target;
52
- };
53
-
54
- return _extends$1.apply(this, arguments);
55
- }
56
-
57
- const ANY_CONTENT_TYPE = "*/*";
58
- /**
59
- * @ignore
60
- */
61
-
62
- function getContentType(data, ctx) {
63
- const {
64
- endpoint,
65
- response
66
- } = ctx;
67
- const {
68
- operation
69
- } = endpoint;
70
- const contentType = response.getContentType() || operation.getContentTypeOf(response.statusCode) || "";
71
-
72
- if (contentType && contentType !== ANY_CONTENT_TYPE) {
73
- if (contentType === "application/json") {
74
- if (core.isObject(data)) {
75
- return contentType;
76
- }
77
- } else {
78
- return contentType;
79
- }
80
- }
81
-
82
- if (typeof data === "string" && endpoint.view) {
83
- return "text/html";
84
- }
85
- }
86
-
87
- /**
88
- * @ignore
89
- */
90
- // tslint:disable-next-line:variable-name
91
-
92
- const JsonMapperTypesContainer = new Map();
93
- /**
94
- * @ignore
95
- */
96
-
97
- function registerJsonTypeMapper(type, token) {
98
- JsonMapperTypesContainer.set(type, new token());
99
- }
100
- /**
101
- * @ignore
102
- */
103
-
104
-
105
- function getJsonMapperTypes() {
106
- return JsonMapperTypesContainer;
107
- }
108
- /**
109
- * Register a new JsonMapper Type
110
- * @param types
111
- * @constructor
112
- */
113
-
114
-
115
- function JsonMapper(...types) {
116
- return target => {
117
- types.forEach(type => {
118
- registerJsonTypeMapper(type, target);
119
- });
120
- };
121
- }
122
- /**
123
- * Mapper for `Array` type.
124
- * @jsonmapper
125
- * @component
126
- */
127
-
128
-
129
- let ArrayMapper = class ArrayMapper {
130
- deserialize(data, options) {
131
- return [].concat(data).map(item => options.next(item));
132
- }
133
-
134
- serialize(data, options) {
135
- return [].concat(data).map(item => options.next(item));
136
- }
137
-
138
- };
139
- ArrayMapper = tslib.__decorate([JsonMapper(Array)], ArrayMapper);
140
- /**
141
- * Mapper for `Date` type.
142
- * @jsonmapper
143
- * @component
144
- */
145
-
146
- let DateMapper = class DateMapper {
147
- deserialize(data) {
148
- // don't convert unexpected data. In normal case, Ajv reject unexpected data.
149
- // But by default, we have to skip data deserialization and let user to apply
150
- // the right mapping
151
- if (core.isBoolean(data) || data === null || data === undefined) {
152
- return data;
153
- }
154
-
155
- return new Date(data);
156
- }
157
-
158
- serialize(object) {
159
- return new Date(object).toISOString();
160
- }
161
-
162
- };
163
- DateMapper = tslib.__decorate([JsonMapper(Date)], DateMapper);
164
- /**
165
- * Mapper for `Map` type.
166
- * @jsonmapper
167
- * @component
168
- */
169
-
170
- let MapMapper = class MapMapper {
171
- deserialize(data, ctx) {
172
- const obj = new Map();
173
- core.objectKeys(data).forEach(key => {
174
- obj.set(key, ctx.next(data[key]));
175
- });
176
- return obj;
177
- }
178
-
179
- serialize(data, ctx) {
180
- const obj = {};
181
- data.forEach((value, key) => obj[key] = ctx.next(value));
182
- return obj;
183
- }
184
-
185
- };
186
- MapMapper = tslib.__decorate([JsonMapper(Map)], MapMapper);
187
- /**
188
- * Mapper for the `String`, `Number` and `Boolean` types.
189
- * @jsonmapper
190
- * @component
191
- */
192
-
193
- let PrimitiveMapper = class PrimitiveMapper {
194
- deserialize(data, ctx) {
195
- switch (ctx.type) {
196
- case String:
197
- return data === null ? null : "" + data;
198
-
199
- case Number:
200
- if ([null, "null"].includes(data)) return null;
201
- const n = +data;
202
-
203
- if (isNaN(n)) {
204
- throw new exceptions.BadRequest("Cast error. Expression value is not a number.");
205
- }
206
-
207
- return n;
208
-
209
- case Boolean:
210
- if (["true", "1", true].includes(data)) return true;
211
- if (["false", "0", false].includes(data)) return false;
212
- if ([null, "null"].includes(data)) return null;
213
- if (data === undefined) return undefined;
214
- return !!data;
215
- }
216
- }
217
-
218
- serialize(object) {
219
- return object;
220
- }
221
-
222
- };
223
- PrimitiveMapper = tslib.__decorate([JsonMapper(String, Number, Boolean)], PrimitiveMapper);
224
- /**
225
- * Mapper for the `Set` Type.
226
- * @jsonmapper
227
- * @component
228
- */
229
-
230
- let SetMapper = class SetMapper {
231
- deserialize(data, ctx) {
232
- const obj = new Set();
233
- core.objectKeys(data).forEach(key => {
234
- obj.add(ctx.next(data[key]));
235
- });
236
- return obj;
237
- }
238
-
239
- serialize(data, ctx) {
240
- const array = [];
241
- data.forEach(value => array.push(ctx.next(value)));
242
- return array;
243
- }
244
-
245
- };
246
- SetMapper = tslib.__decorate([JsonMapper(Set)], SetMapper);
247
- /**
248
- * Mapper for the `Symbol` type.
249
- *
250
- * @jsonmapper
251
- * @component
252
- */
253
-
254
- let SymbolMapper = class SymbolMapper {
255
- deserialize(data) {
256
- return Symbol.for(data);
257
- }
258
-
259
- serialize(object) {
260
- return object.toString().replace("Symbol(", "").replace(")", "");
261
- }
262
-
263
- };
264
- SymbolMapper = tslib.__decorate([JsonMapper(Symbol)], SymbolMapper);
265
-
266
- function _extends() {
267
- _extends = Object.assign || function (target) {
268
- for (var i = 1; i < arguments.length; i++) {
269
- var source = arguments[i];
270
-
271
- for (var key in source) {
272
- if (Object.prototype.hasOwnProperty.call(source, key)) {
273
- target[key] = source[key];
274
- }
275
- }
276
- }
277
-
278
- return target;
279
- };
280
-
281
- return _extends.apply(this, arguments);
282
- }
283
-
284
- function _objectWithoutPropertiesLoose(source, excluded) {
285
- if (source == null) return {};
286
- var target = {};
287
- var sourceKeys = Object.keys(source);
288
- var key, i;
289
-
290
- for (i = 0; i < sourceKeys.length; i++) {
291
- key = sourceKeys[i];
292
- if (excluded.indexOf(key) >= 0) continue;
293
- target[key] = source[key];
294
- }
295
-
296
- return target;
297
- }
298
- /**
299
- * @ignore
300
- */
301
-
302
-
303
- class JsonMapperContext {
304
- constructor({
305
- type,
306
- collectionType,
307
- next,
308
- options
309
- }) {
310
- this.type = type;
311
- this.collectionType = core.isCollection(collectionType) ? collectionType : undefined;
312
- this._next = next;
313
- this.options = options;
314
- }
315
-
316
- next(data) {
317
- return this._next(data, _extends({}, this.options, {
318
- type: this.type
319
- }));
320
- }
321
-
322
- }
323
-
324
- const _excluded = ["useAlias", "type"],
325
- _excluded2 = ["type", "collectionType", "groups"];
326
-
327
- function alterValue(schema, value, options) {
328
- return schema.$hooks.alter("onSerialize", value, [options]);
329
- }
330
-
331
- function getSchemaProperties(storedJson, obj) {
332
- const stores = Array.from(schema.getPropertiesStores(storedJson).entries());
333
-
334
- if (!stores.length) {
335
- // fallback to auto discovering field from obj
336
- core.objectKeys(obj).forEach(key => {
337
- const propStore = schema.JsonEntityStore.from(core.classOf(storedJson.target), key);
338
- stores.push([key, propStore]);
339
- });
340
- }
341
-
342
- return stores;
343
- }
344
-
345
- function getObjectProperties(obj) {
346
- return Object.entries(obj).filter(([, value]) => !core.isFunction(value));
347
- }
348
-
349
- function getType(propStore, value) {
350
- if (core.isNil(value) || propStore.type === Object || core.isCollection(propStore.type)) {
351
- return undefined;
352
- }
353
-
354
- return propStore.type;
355
- }
356
-
357
- function classToPlainObject(obj, options) {
358
- const {
359
- useAlias = true,
360
- type
361
- } = options,
362
- props = _objectWithoutPropertiesLoose(options, _excluded);
363
-
364
- const entity = schema.JsonEntityStore.from(type || obj);
365
- return getSchemaProperties(entity, obj).reduce((newObj, [key, propStore]) => {
366
- const schema$1 = propStore.schema;
367
-
368
- if (schema.alterIgnore(schema$1, _extends({
369
- useAlias
370
- }, props, {
371
- self: obj
372
- }))) {
373
- return newObj;
374
- }
375
-
376
- let value = alterValue(schema$1, obj[key], _extends({
377
- useAlias
378
- }, props, {
379
- self: obj
380
- }));
381
- value = serialize(value, _extends({
382
- useAlias,
383
- type: value === obj[key] ? getType(propStore, value) : undefined,
384
- collectionType: propStore.collectionType
385
- }, props));
386
-
387
- if (value === undefined) {
388
- return newObj;
389
- }
390
-
391
- key = useAlias ? propStore.parent.schema.getAliasOf(key) || key : key;
392
- return _extends({}, newObj, {
393
- [key]: value
394
- });
395
- }, {});
396
- }
397
-
398
- function toObject(obj, options) {
399
- return getObjectProperties(obj).reduce((newObj, [key, value]) => _extends({}, newObj, {
400
- [key]: serialize(value, options)
401
- }), {});
402
- }
403
-
404
- function serialize(obj, _ref = {}) {
405
- let {
406
- type,
407
- groups = false
408
- } = _ref,
409
- options = _objectWithoutPropertiesLoose(_ref, _excluded2);
410
-
411
- const types = options.types ? options.types : getJsonMapperTypes(); // prevent Object metadata assignation. TypeScript set Object by default on endpoint.type
412
-
413
- type = type === Object ? undefined : type;
414
- options.groups = groups;
415
-
416
- if (core.isEmpty(obj)) {
417
- return obj;
418
- } // FIX custom serialization function from @tsed/mongoose
419
-
420
-
421
- if (typeof obj.toJSON === "function" && obj.$isMongooseModelPrototype) {
422
- return obj.toJSON(options);
423
- }
424
-
425
- if (typeof obj.toJSON === "function") {
426
- return serialize(obj.toJSON(), _extends({}, options, {
427
- type: core.classOf(obj)
428
- }));
429
- }
430
-
431
- if (type && core.isClass(type)) {
432
- options.type = type;
433
- }
434
-
435
- if (core.isCollection(obj) && !options.collectionType) {
436
- type = core.classOf(obj);
437
- options.collectionType = type;
438
- }
439
-
440
- type = core.classOf(type || obj);
441
- const context = new JsonMapperContext({
442
- type,
443
- options,
444
- next: data => serialize(data, _extends({}, options, {
445
- collectionType: undefined,
446
- type: options.type
447
- }))
448
- });
449
-
450
- if (types.has(type)) {
451
- const jsonMapper = types.get(type);
452
- return jsonMapper.serialize(obj, context);
453
- }
454
-
455
- if (core.isArray(obj)) {
456
- var _types$get; // Serialize Array class like
457
-
458
-
459
- return (_types$get = types.get(Array)) == null ? void 0 : _types$get.serialize(obj, context);
460
- }
461
-
462
- return !core.isClassObject(core.classOf(type)) ? classToPlainObject(obj, options) : toObject(obj, options);
463
- }
464
-
465
- /**
466
- * @platform
467
- */
468
-
469
- exports.PlatformResponseFilter = class PlatformResponseFilter {
470
- constructor() {
471
- this.types = new Map();
472
- }
473
-
474
- get contentTypes() {
475
- return [...this.types.keys()];
476
- }
477
-
478
- $onInit() {
479
- ResponseFiltersContainer.forEach((token, type) => {
480
- if (this.responseFilters.includes(token)) {
481
- this.types.set(type, this.injector.get(token));
482
- }
483
- });
484
- }
485
-
486
- getBestContentType(data, ctx) {
487
- const contentType = getContentType(data, ctx);
488
-
489
- if (ctx.request.get("Accept")) {
490
- const bestContentType = ctx.request.accepts([contentType].concat(this.contentTypes).filter(Boolean));
491
-
492
- if (bestContentType) {
493
- return [].concat(bestContentType).filter(type => type !== "*/*")[0];
494
- }
495
- }
496
-
497
- return contentType;
498
- }
499
- /**
500
- * Call filters to transform data
501
- * @param data
502
- * @param ctx
503
- */
504
-
505
-
506
- async transform(data, ctx) {
507
- const {
508
- response
509
- } = ctx;
510
- const bestContentType = this.getBestContentType(data, ctx);
511
- bestContentType && response.contentType(bestContentType);
512
-
513
- if (this.types.has(bestContentType)) {
514
- return this.types.get(bestContentType).transform(data, ctx);
515
- }
516
-
517
- if (this.types.has(ANY_CONTENT_TYPE)) {
518
- return this.types.get(ANY_CONTENT_TYPE).transform(data, ctx);
519
- }
520
-
521
- return data;
522
- }
523
- /**
524
- * Serialize data from endpoint metadata
525
- * @param data
526
- * @param ctx
527
- */
528
-
529
-
530
- async serialize(data, ctx) {
531
- const {
532
- response,
533
- endpoint
534
- } = ctx;
535
-
536
- if (endpoint) {
537
- if (endpoint.view) {
538
- data = await platformViews.renderView(data, ctx);
539
- } else if (core.isSerializable(data)) {
540
- data = serialize(data, _extends$1({}, endpoint.getResponseOptions(response.statusCode), {
541
- additionalProperties: this.additionalProperties,
542
- useAlias: true,
543
- endpoint: true
544
- }));
545
- }
546
- }
547
-
548
- return data;
549
- }
550
-
551
- };
552
-
553
- tslib.__decorate([di.Inject(), tslib.__metadata("design:type", di.InjectorService)], exports.PlatformResponseFilter.prototype, "injector", void 0);
554
-
555
- tslib.__decorate([di.Constant("responseFilters", []), tslib.__metadata("design:type", Array)], exports.PlatformResponseFilter.prototype, "responseFilters", void 0);
556
-
557
- tslib.__decorate([di.Constant("additionalProperties"), tslib.__metadata("design:type", Boolean)], exports.PlatformResponseFilter.prototype, "additionalProperties", void 0);
558
-
559
- exports.PlatformResponseFilter = tslib.__decorate([di.Injectable()], exports.PlatformResponseFilter);
560
-
561
- exports.ANY_CONTENT_TYPE = ANY_CONTENT_TYPE;
562
- exports.ResponseFilter = ResponseFilter;
563
- exports.ResponseFiltersContainer = ResponseFiltersContainer;
564
- exports.getContentType = getContentType;
565
- exports.registerResponseFilter = registerResponseFilter;
566
- //# sourceMappingURL=index.js.map