@smartlyio/oats-runtime 4.3.2 → 4.4.1-alpha.14

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.
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { Type } from './reflection-type';
2
+ export declare function withType<A>(to: A, type: Type[]): A;
3
+ export declare function getTypeSet(value: Record<string, any>): Set<Type> | undefined;
4
+ /** Get reflection type from a made value.
5
+ * Note that only directly made object values or ValueClasses can be used
6
+ * */
7
+ export declare function getType(value: Record<string, any>): Type[] | undefined;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getType = exports.getTypeSet = exports.withType = void 0;
4
+ const value_class_1 = require("./value-class");
5
+ function withType(to, type) {
6
+ if (type.length === 0) {
7
+ return to;
8
+ }
9
+ // todo: is it possible to confuse typing by re-use of valueclassed values
10
+ // eg. with value 'v: SomeValueClass' passing it to multiple makers
11
+ // -> no? the re-use happens only if the valueclass instance matches so it
12
+ // will not mutate the tagged reflection types
13
+ const previous = getTypeSet(to);
14
+ if (previous) {
15
+ type.forEach(type => previous.add(type));
16
+ return to;
17
+ }
18
+ const newType = new Set(type);
19
+ // tag each constructed object with a hidden type property
20
+ Object.defineProperty(to, reflection, {
21
+ enumerable: false,
22
+ value: newType
23
+ });
24
+ return to;
25
+ }
26
+ exports.withType = withType;
27
+ function getTypeSet(value) {
28
+ if (!value || typeof value !== 'object') {
29
+ return;
30
+ }
31
+ // NOTE: prefer using the added reflection type instead of the contstructor type
32
+ // the added reflection type will have types from eg allOf
33
+ // @ts-ignore
34
+ const t = value[reflection];
35
+ if (t && t.size > 0) {
36
+ return t;
37
+ }
38
+ if (value instanceof value_class_1.ValueClass) {
39
+ // a bit of leap here to trust that all ValueClasses have generated `reflection`
40
+ // @ts-ignore
41
+ const classType = new Set([value.constructor.reflection().definition]);
42
+ // tag each constructed object with a hidden type property
43
+ // this ensures that ValueClasses have a mutable reflection type property
44
+ Object.defineProperty(value, reflection, {
45
+ enumerable: false,
46
+ value: classType
47
+ });
48
+ return classType;
49
+ }
50
+ return;
51
+ }
52
+ exports.getTypeSet = getTypeSet;
53
+ /** Get reflection type from a made value.
54
+ * Note that only directly made object values or ValueClasses can be used
55
+ * */
56
+ function getType(value) {
57
+ const t = getTypeSet(value);
58
+ if (t) {
59
+ return [...t];
60
+ }
61
+ }
62
+ exports.getType = getType;
63
+ const reflection = Symbol('reflection');
64
+ //# sourceMappingURL=type-tag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-tag.js","sourceRoot":"","sources":["../src/type-tag.ts"],"names":[],"mappings":";;;AACA,+CAA2C;AAE3C,SAAgB,QAAQ,CAAI,EAAK,EAAE,IAAY;IAC7C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;QACrB,OAAO,EAAE,CAAC;KACX;IACD,0EAA0E;IAC1E,oEAAoE;IACpE,0EAA0E;IAC1E,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;IAChC,IAAI,QAAQ,EAAE;QACZ,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACzC,OAAO,EAAE,CAAC;KACX;IACD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,0DAA0D;IAC1D,MAAM,CAAC,cAAc,CAAC,EAAE,EAAE,UAAU,EAAE;QACpC,UAAU,EAAE,KAAK;QACjB,KAAK,EAAE,OAAO;KACf,CAAC,CAAC;IACH,OAAO,EAAE,CAAC;AACZ,CAAC;AApBD,4BAoBC;AAED,SAAgB,UAAU,CAAC,KAA0B;IACnD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QACvC,OAAO;KACR;IAED,gFAAgF;IAChF,0DAA0D;IAC1D,aAAa;IACb,MAAM,CAAC,GAAc,KAAK,CAAC,UAAU,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE;QACnB,OAAO,CAAC,CAAC;KACV;IACD,IAAI,KAAK,YAAY,wBAAU,EAAE;QAC/B,gFAAgF;QAChF,aAAa;QACb,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QACvE,0DAA0D;QAC1D,yEAAyE;QACzE,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE;YACvC,UAAU,EAAE,KAAK;YACjB,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;KAClB;IACD,OAAO;AACT,CAAC;AAzBD,gCAyBC;AAED;;KAEK;AACL,SAAgB,OAAO,CAAC,KAA0B;IAChD,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;KACf;AACH,CAAC;AALD,0BAKC;AAED,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC"}
package/jest.config.js ADDED
@@ -0,0 +1,38 @@
1
+ module.exports = {
2
+ moduleFileExtensions: ['js', 'ts', 'tsx'],
3
+ moduleNameMapper: {
4
+ "@smartlyio/oats$": "<rootDir>/packages/oats/index.ts",
5
+ "@smartlyio/oats-runtime$": "<rootDir>/packages/oats-runtime/src/runtime.ts",
6
+ "@smartlyio/oats-axios-adapter$": "<rootDir>/packages/oats-axios-adapter/index.ts",
7
+ "@smartlyio/oats-koa-adapter$": "<rootDir>/packages/oats-koa-adapter/index.ts",
8
+ "@smartlyio/oats-fast-check$": "<rootDir>/packages/oats-fast-check/src/index.ts"
9
+ },
10
+
11
+ testRegex: '.*\\.spec.(tsx?)$',
12
+
13
+ collectCoverageFrom: [
14
+ 'packages/*/src/**/*.{ts,tsxx}',
15
+ '!packages/*/src/**/*.story.*'
16
+ ],
17
+
18
+ coverageThreshold: {
19
+ global: {
20
+ branches: 20,
21
+ statements: 20,
22
+ },
23
+ },
24
+
25
+ modulePathIgnorePatterns: ['<rootDir>/packages/*/dist'],
26
+
27
+ transform: {
28
+ '^.+\\.(ts|js)x?$': 'ts-jest',
29
+ },
30
+
31
+ globals: {
32
+ 'ts-jest': {
33
+ isolatedModules: true,
34
+ diagnostics: true,
35
+ },
36
+ },
37
+ setupFilesAfterEnv: [],
38
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartlyio/oats-runtime",
3
- "version": "4.3.2",
3
+ "version": "4.4.1-alpha.14+d4dd547",
4
4
  "license": "MIT",
5
5
  "description": "Runtime for Oats a Openapi3 based generator for typescript aware servers and clients",
6
6
  "private": false,
@@ -24,7 +24,7 @@
24
24
  "dependencies": {
25
25
  "@smartlyio/safe-navigation": "^5.0.1",
26
26
  "@types/encodeurl": "1.0.0",
27
- "@types/escape-html": "1.0.1",
27
+ "@types/escape-html": "1.0.2",
28
28
  "encodeurl": "1.0.2",
29
29
  "escape-html": "1.0.3",
30
30
  "lodash": "^4.17.20"
@@ -42,7 +42,7 @@
42
42
  "@types/jest": "27.4.1",
43
43
  "@types/lodash": "4.14.181",
44
44
  "@types/node": "16.11.26",
45
- "fast-check": "2.24.0",
45
+ "fast-check": "2.25.0",
46
46
  "jest": "27.5.1",
47
47
  "jsverify": "0.8.4",
48
48
  "prettier": "2.6.2",
@@ -51,5 +51,5 @@
51
51
  "tsconfig-paths": "3.14.1",
52
52
  "typescript": "4.6.3"
53
53
  },
54
- "gitHead": "8e6ff688c82fb559b853f01041343441be32e15a"
54
+ "gitHead": "d4dd547c8a58901fe83141514a18b665d48288a5"
55
55
  }
package/src/client.ts CHANGED
@@ -184,7 +184,8 @@ function makeMethod(adapter: ClientAdapter, handler: server.Handler, pathParams:
184
184
  handler.body,
185
185
  handler.response,
186
186
  ctx =>
187
- adapter({ ...ctx, path: fillInPathParams(params, handler.path), servers: handler.servers })
187
+ adapter({ ...ctx, path: fillInPathParams(params, handler.path), servers: handler.servers }),
188
+ { mode: 'client' }
188
189
  );
189
190
  return (ctx: ClientArg<any, any, any>) =>
190
191
  call({
package/src/make.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { assert, fail } from './assert';
2
2
  import safe from '@smartlyio/safe-navigation';
3
3
  import * as _ from 'lodash';
4
+ import { isEqual, uniq } from 'lodash';
4
5
  import { ValueClass } from './value-class';
5
6
  import { NamedTypeDefinition, ObjectType, Type } from './reflection-type';
6
7
  import { discriminateUnion } from './union-discriminator';
7
- import { isEqual, uniq } from 'lodash';
8
+ import { getType, getTypeSet, withType } from './type-tag';
8
9
 
9
10
  export class MakeError extends Error {
10
11
  constructor(readonly errors: ValidationError[]) {
@@ -122,6 +123,9 @@ export interface MakeOptions {
122
123
  * (if query parameter is not repeated, it will not be an array on server side).
123
124
  */
124
125
  allowConvertForArrayType?: boolean;
126
+
127
+ /** If true convert property names from network to ts format while parsing objects */
128
+ convertFromNetwork?: boolean;
125
129
  }
126
130
 
127
131
  export type Maker<Shape, V> = (value: Shape, opts?: MakeOptions) => Make<V>;
@@ -363,16 +367,18 @@ export function makeOneOf(...options: any[]) {
363
367
  };
364
368
  }
365
369
 
366
- export function makeAllOf(...all: any[]) {
370
+ export function makeAllOf(...all: Maker<any, any>[]) {
367
371
  return (value: any, opts?: MakeOptions) => {
372
+ const types = [];
368
373
  for (const make of all) {
369
374
  const result: Make<any> = make(value, opts);
370
375
  if (result.isError()) {
371
376
  return result.errorPath('(allOf)');
372
377
  }
373
378
  value = result.success();
379
+ types.push(...(getTypeSet(value) ?? []));
374
380
  }
375
- return Make.ok(value);
381
+ return Make.ok(withType(value, types));
376
382
  };
377
383
  }
378
384
 
@@ -380,9 +386,42 @@ function isMagic(field: string) {
380
386
  return ['__proto__', 'constructor'].indexOf(field) >= 0;
381
387
  }
382
388
 
389
+ function getInputPropName(args: {
390
+ value: any;
391
+ index: string;
392
+ fromNetwork: Record<string, string>;
393
+ opts?: MakeOptions;
394
+ }) {
395
+ if (!args.opts?.convertFromNetwork) {
396
+ return args.index;
397
+ }
398
+ const types = getType(args.value) ?? [];
399
+ const networkProp = args.fromNetwork?.[args.index] ?? args.index;
400
+ for (const type of types) {
401
+ if (type.type !== 'object') {
402
+ // only objects can have network mappings
403
+ continue;
404
+ }
405
+ const mapped = type.properties[args.index];
406
+ if (mapped) {
407
+ // if the object was made already then network mapping has been done for listed properties
408
+ // and we should use the ts side property
409
+ assert(
410
+ networkProp == mapped.networkName,
411
+ `Network names for properties with the same name need to be equal when a object has multiple types. Mismatch in ${networkProp} and ${mapped.networkName}.`
412
+ );
413
+ return args.index;
414
+ }
415
+ }
416
+ return networkProp;
417
+ }
418
+
383
419
  export function makeObject<
384
420
  P extends { [key: string]: Maker<any, any> | { optional: Maker<any, any> } }
385
- >(props: P, additionalProp?: any, comparisorOrder?: string[]) {
421
+ >(props: P, additionalProp?: any, comparisorOrder?: string[], type?: ObjectType) {
422
+ const fromNetwork = fromNetworkMap(type);
423
+ const listedInputPropNames = new Set(Object.keys(props).map(prop => fromNetwork[prop] ?? prop));
424
+
386
425
  return (value: any, opts?: MakeOptions) => {
387
426
  if (typeof value !== 'object' || value == null || Array.isArray(value)) {
388
427
  return getErrorWithValueMsg('expected an object', value);
@@ -393,26 +432,32 @@ export function makeObject<
393
432
  if (isMagic(index)) {
394
433
  return error(`Using ${index} as field of an object is not allowed`);
395
434
  }
435
+ const inputPropName = getInputPropName({ opts, index, fromNetwork, value });
396
436
  let maker: any = props[index];
397
437
  if (!maker) {
398
438
  return error(`Prop maker not found for key ${index}. This is likely a bug in oats`);
399
439
  }
400
440
  if (maker.optional) {
401
- if (!(index in value) || value[index] === undefined) {
441
+ if (!(inputPropName in value) || value[inputPropName] === undefined) {
402
442
  continue;
403
443
  }
404
444
  maker = maker.optional;
405
445
  }
406
- const propResult: Make<any> = maker(value[index], opts);
446
+ const propResult: Make<any> = maker(value[inputPropName], opts);
407
447
  if (propResult.isError()) {
408
448
  return propResult.errorPath(index);
409
449
  }
410
450
  result[index] = propResult.success();
411
451
  }
412
452
  for (const index of Object.keys(value)) {
453
+ // do not consider props that got mapped
454
+ if (opts?.convertFromNetwork && listedInputPropNames.has(index)) {
455
+ continue;
456
+ }
413
457
  if (isMagic(index)) {
414
458
  return error(`Using ${index} as objects additional field is not allowed.`);
415
459
  }
460
+ // do not allow overriding mapped props
416
461
  if (props[index]) {
417
462
  continue;
418
463
  }
@@ -428,7 +473,11 @@ export function makeObject<
428
473
  }
429
474
  result[index] = propResult.success();
430
475
  }
431
- return Make.ok(result);
476
+ const oldType = getType(value);
477
+ if (oldType) {
478
+ withType(result, oldType);
479
+ }
480
+ return Make.ok(withType(result, type ? [type] : []));
432
481
  };
433
482
  }
434
483
 
@@ -542,12 +591,26 @@ function priority(v: ObjectType['properties'][string]) {
542
591
  return Priority.NonScalar;
543
592
  }
544
593
 
594
+ function fromNetworkMap(type?: ObjectType) {
595
+ if (!type) {
596
+ return {};
597
+ }
598
+ const fromNetwork = Object.keys(type.properties).reduce<Record<string, string>>((memo, key) => {
599
+ const mapped = type.properties[key].networkName;
600
+ if (mapped) {
601
+ memo[key] = mapped;
602
+ }
603
+ return memo;
604
+ }, {});
605
+ return fromNetwork;
606
+ }
545
607
  function fromObjectReflection(type: ObjectType): Maker<any, any> {
546
608
  const comparisonOrder = Object.keys(type.properties).sort((aKey, bKey) => {
547
609
  const a = type.properties[aKey]!;
548
610
  const b = type.properties[bKey]!;
549
611
  return priority(a) - priority(b);
550
612
  });
613
+
551
614
  return makeObject(
552
615
  Object.entries(type.properties).reduce(
553
616
  (memo, [key, prop]) => ({
@@ -561,7 +624,8 @@ function fromObjectReflection(type: ObjectType): Maker<any, any> {
561
624
  ? makeAny()
562
625
  : fromReflection(type.additionalProperties)
563
626
  : undefined,
564
- comparisonOrder
627
+ comparisonOrder,
628
+ type
565
629
  );
566
630
  }
567
631
 
@@ -96,6 +96,7 @@ export interface NamedType {
96
96
  export interface PropType {
97
97
  required: boolean;
98
98
  value: Type;
99
+ networkName?: string;
99
100
  }
100
101
 
101
102
  export interface Props {
package/src/runtime.ts CHANGED
@@ -4,12 +4,16 @@ import * as make from './make';
4
4
  import { fromReflection } from './make';
5
5
  import * as valueClass from './value-class';
6
6
  import * as reflection from './reflection-type';
7
+ import * as typeTag from './type-tag';
8
+ import { ValueClass } from './value-class';
7
9
 
8
10
  export { redirect } from './redirect';
9
11
 
10
12
  export { make, fromReflection, server, client, valueClass, reflection };
11
13
 
12
14
  export const noContentContentType = 'oatsNoContent' as const;
15
+ export { serialize } from './serialize';
16
+ export { getType, withType } from './type-tag';
13
17
 
14
18
  type Scalar = number | string | boolean;
15
19
 
@@ -18,6 +22,23 @@ const tagKey = Symbol();
18
22
 
19
23
  type ScalarWithoutBrand<V> = V extends ShapedClass<infer S> ? ScalarWithoutBrand<S> : V;
20
24
 
25
+ // helper to set necessary metadata for valueclass instances
26
+ export function instanceAssign(
27
+ to: ValueClass,
28
+ value: Record<string, unknown>,
29
+ opts: make.MakeOptions | { unSafeSet: boolean } | undefined,
30
+ builder: make.Maker<any, any>
31
+ ) {
32
+ Object.assign(to, opts && 'unSafeSet' in opts ? value : builder(value, opts).success());
33
+ // when we create an instance of a ValueClass we need to propagate the type information from 'value' to the newly
34
+ // constructed instance
35
+ const existingType = typeTag.getType(value);
36
+ if (existingType) {
37
+ return typeTag.withType(to, existingType);
38
+ }
39
+ return to;
40
+ }
41
+
21
42
  export type ShapeOf<A> = A extends Scalar
22
43
  ? ScalarWithoutBrand<A>
23
44
  : A extends ShapedClass<infer S>
@@ -0,0 +1,28 @@
1
+ import { getType } from './type-tag';
2
+
3
+ export function serialize(value: any): any {
4
+ if (Array.isArray(value)) {
5
+ return value.map(v => serialize(v));
6
+ }
7
+ const types = getType(value);
8
+ if (!types) {
9
+ return value;
10
+ }
11
+ return types.reduce((value, type) => {
12
+ switch (type.type) {
13
+ case 'object':
14
+ return Object.keys(value).reduce<Record<string, any>>((memo, key) => {
15
+ const prop = type.properties[key];
16
+ const networkProp = prop && prop.networkName ? prop.networkName : key;
17
+ // serializing the same value multiple times is ok but unnecessary so long
18
+ // as the mappings in different objects match. If that is not the case we are screwed.
19
+ if (memo[networkProp] === undefined) {
20
+ memo[networkProp] = serialize(value[key]);
21
+ }
22
+ return memo;
23
+ }, {});
24
+ default:
25
+ return value;
26
+ }
27
+ }, value);
28
+ }
package/src/server.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { assert } from './assert';
2
2
  import safeNavigation from '@smartlyio/safe-navigation';
3
3
  import { Make, MakeOptions, Maker, ValidationError, validationErrorPrinter } from './make';
4
+ import { serialize } from './serialize';
4
5
 
5
6
  export type { RedirectStatus } from './redirect';
6
7
 
@@ -128,17 +129,34 @@ function voidify(value: object | undefined | null) {
128
129
  return null;
129
130
  }
130
131
 
131
- function cleanHeaders<H>(maker: Maker<any, H>, headers: object) {
132
- const normalized = voidify(lowercaseObject(headers));
132
+ function cleanHeaders<H>(mode: Mode, maker: Maker<any, H>, headers: object) {
133
+ // note: we now expect that on client side headers are type conforming so do not need to lowercase those
134
+ // this is slightly breaking change is somebody has subverted the type checker
135
+ const normalized = voidify(mode === 'server' ? lowercaseObject(headers) : headers);
133
136
  const acceptsNull = maker(null);
134
137
  if (acceptsNull.isSuccess()) {
135
138
  return acceptsNull.success();
136
139
  }
137
140
  return maker(normalized, {
138
- unknownField: 'drop'
141
+ unknownField: 'drop',
142
+ convertFromNetwork: mode === 'server'
139
143
  }).success(throwRequestValidationError.bind(null, 'headers'));
140
144
  }
141
145
 
146
+ function serializeWhenClient(mode: Mode, value: any) {
147
+ if (mode === 'client') {
148
+ return serialize(value);
149
+ }
150
+ return value;
151
+ }
152
+
153
+ function getOutBody<Body extends RequestBody<any>>(mode: Mode, value: Body): Body {
154
+ if (!value) {
155
+ return value;
156
+ }
157
+ return { contentType: value.contentType, value: serializeWhenClient(mode, value.value) } as Body;
158
+ }
159
+
142
160
  export function safe<
143
161
  H extends Headers,
144
162
  P extends Params,
@@ -153,7 +171,7 @@ export function safe<
153
171
  body: Maker<any, Body>,
154
172
  response: Maker<any, R>,
155
173
  endpoint: Endpoint<H, P, Q, Body, R, RC>,
156
- { validationOptions = {} }: HandlerOptions = {}
174
+ { validationOptions = {}, mode }: HandlerOptions & InternalHandlerOptions = { mode: 'client' }
157
175
  ): Endpoint<
158
176
  Headers,
159
177
  Params,
@@ -163,24 +181,51 @@ export function safe<
163
181
  RequestContext
164
182
  > {
165
183
  return async ctx => {
184
+ // note: data coming to client adapter needs to be serialized and data coming from the adapter needs conversion from network
185
+ // note: data coming to server adapter needs to be deserialized and data coming from the adapter needs serialization
186
+ // this is all very clear.
187
+ const internalMakeOptions = { convertFromNetwork: mode === 'server' };
166
188
  const result = await endpoint({
167
189
  path: ctx.path,
168
190
  method: ctx.method,
169
191
  servers: ctx.servers,
170
192
  op: ctx.op,
171
- headers: cleanHeaders(headers, ctx.headers),
172
- params: params(voidify(ctx.params), validationOptions.params).success(
173
- throwRequestValidationError.bind(null, 'params')
193
+ headers: serializeWhenClient(mode, cleanHeaders(mode, headers, ctx.headers)),
194
+ // note: path params come to the adapter in network format always as those are gleaned from the path definition
195
+ params: params(voidify(ctx.params), {
196
+ ...validationOptions.params,
197
+ ...internalMakeOptions,
198
+ convertFromNetwork: true
199
+ }).success(throwRequestValidationError.bind(null, 'params')),
200
+ query: serializeWhenClient(
201
+ mode,
202
+ query(ctx.query || {}, { ...validationOptions.query, ...internalMakeOptions }).success(
203
+ throwRequestValidationError.bind(null, 'query')
204
+ )
174
205
  ),
175
- query: query(ctx.query || {}, validationOptions.query).success(
176
- throwRequestValidationError.bind(null, 'query')
206
+ body: getOutBody<Body>(
207
+ mode,
208
+ body(voidify(ctx.body), internalMakeOptions).success(
209
+ throwRequestValidationError.bind(null, 'body')
210
+ )
177
211
  ),
178
- body: body(voidify(ctx.body)).success(throwRequestValidationError.bind(null, 'body')),
179
212
  requestContext: ctx.requestContext as any
180
213
  });
181
- return response(result).success(
214
+ const responseValue = response(result, { convertFromNetwork: mode === 'client' }).success(
182
215
  throwResponseValidationError.bind(null, `body ${ctx.path}`, result.value.value)
183
216
  );
217
+ if (mode === 'client' || !responseValue) {
218
+ return responseValue;
219
+ }
220
+ // the response must be serialized for transferring from server to client
221
+ return {
222
+ ...responseValue,
223
+ headers: serialize(responseValue.headers),
224
+ value: {
225
+ ...responseValue.value,
226
+ value: serialize(responseValue.value.value)
227
+ }
228
+ };
184
229
  };
185
230
  }
186
231
 
@@ -202,7 +247,7 @@ interface CheckingTree {
202
247
  [method: string]: {
203
248
  safeHandler: (
204
249
  e: Endpoint<any, any, any, any, any, any>,
205
- opts?: HandlerOptions
250
+ opts?: HandlerOptions & InternalHandlerOptions
206
251
  ) => SafeEndpoint;
207
252
  op: string;
208
253
  servers: string[];
@@ -228,7 +273,10 @@ function createTree(handlers: Handler[]): CheckingTree {
228
273
  memo[element.path] = {};
229
274
  }
230
275
  memo[element.path][element.method] = {
231
- safeHandler: (e: Endpoint<any, any, any, any, any, any>, opts?: HandlerOptions) =>
276
+ safeHandler: (
277
+ e: Endpoint<any, any, any, any, any, any>,
278
+ opts?: HandlerOptions & InternalHandlerOptions
279
+ ) =>
232
280
  safe(
233
281
  element.headers,
234
282
  element.params,
@@ -260,6 +308,15 @@ export type ServerAdapter = (
260
308
  servers: string[]
261
309
  ) => void;
262
310
 
311
+ type Mode = 'client' | 'server';
312
+ export interface InternalHandlerOptions {
313
+ /** whether we are calling this on client side or in server side.
314
+ * This may have effect on eg network <-> ts property mapping.
315
+ * This value is set automatically by oats.
316
+ * */
317
+ mode: Mode;
318
+ }
319
+
263
320
  export interface HandlerOptions {
264
321
  /**
265
322
  * Options for request schema validation.
@@ -287,7 +344,7 @@ export function createHandlerFactory<Spec>(
287
344
  path,
288
345
  endpointWrapper.op,
289
346
  assertMethod(method),
290
- endpointWrapper.safeHandler(methodHandler, opts),
347
+ endpointWrapper.safeHandler(methodHandler, { ...opts, mode: 'server' }),
291
348
  endpointWrapper.servers
292
349
  );
293
350
  });
@@ -0,0 +1,63 @@
1
+ import { Type } from './reflection-type';
2
+ import { ValueClass } from './value-class';
3
+
4
+ export function withType<A>(to: A, type: Type[]): A {
5
+ if (type.length === 0) {
6
+ return to;
7
+ }
8
+ // todo: is it possible to confuse typing by re-use of valueclassed values
9
+ // eg. with value 'v: SomeValueClass' passing it to multiple makers
10
+ // -> no? the re-use happens only if the valueclass instance matches so it
11
+ // will not mutate the tagged reflection types
12
+ const previous = getTypeSet(to);
13
+ if (previous) {
14
+ type.forEach(type => previous.add(type));
15
+ return to;
16
+ }
17
+ const newType = new Set(type);
18
+ // tag each constructed object with a hidden type property
19
+ Object.defineProperty(to, reflection, {
20
+ enumerable: false,
21
+ value: newType
22
+ });
23
+ return to;
24
+ }
25
+
26
+ export function getTypeSet(value: Record<string, any>): Set<Type> | undefined {
27
+ if (!value || typeof value !== 'object') {
28
+ return;
29
+ }
30
+
31
+ // NOTE: prefer using the added reflection type instead of the contstructor type
32
+ // the added reflection type will have types from eg allOf
33
+ // @ts-ignore
34
+ const t: Set<Type> = value[reflection];
35
+ if (t && t.size > 0) {
36
+ return t;
37
+ }
38
+ if (value instanceof ValueClass) {
39
+ // a bit of leap here to trust that all ValueClasses have generated `reflection`
40
+ // @ts-ignore
41
+ const classType = new Set([value.constructor.reflection().definition]);
42
+ // tag each constructed object with a hidden type property
43
+ // this ensures that ValueClasses have a mutable reflection type property
44
+ Object.defineProperty(value, reflection, {
45
+ enumerable: false,
46
+ value: classType
47
+ });
48
+ return classType;
49
+ }
50
+ return;
51
+ }
52
+
53
+ /** Get reflection type from a made value.
54
+ * Note that only directly made object values or ValueClasses can be used
55
+ * */
56
+ export function getType(value: Record<string, any>): Type[] | undefined {
57
+ const t = getTypeSet(value);
58
+ if (t) {
59
+ return [...t];
60
+ }
61
+ }
62
+
63
+ const reflection = Symbol('reflection');