@typespec/http-server-js 0.58.0-alpha.18-dev.2 → 0.58.0-alpha.18-dev.3
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.
- package/dist/src/common/scalar.d.ts.map +1 -1
- package/dist/src/common/scalar.js +9 -1
- package/dist/src/common/scalar.js.map +1 -1
- package/dist/src/http/server/index.d.ts.map +1 -1
- package/dist/src/http/server/index.js +33 -11
- package/dist/src/http/server/index.js.map +1 -1
- package/dist/src/util/differentiate.d.ts +11 -1
- package/dist/src/util/differentiate.d.ts.map +1 -1
- package/dist/src/util/differentiate.js +17 -1
- package/dist/src/util/differentiate.js.map +1 -1
- package/package.json +1 -1
- package/src/common/scalar.ts +9 -1
- package/src/http/server/index.ts +45 -23
- package/src/util/differentiate.ts +32 -0
- package/temp/tsconfig.tsbuildinfo +1 -1
- package/test/e2e/http/type/array/main.test.e2e.ts +78 -0
- package/test/e2e/http/type/dictionary/main.test.e2e.ts +86 -0
package/src/http/server/index.ts
CHANGED
|
@@ -45,6 +45,7 @@ import { getJsScalar } from "../../common/scalar.js";
|
|
|
45
45
|
import {
|
|
46
46
|
requiresJsonSerialization,
|
|
47
47
|
transposeExpressionFromJson,
|
|
48
|
+
transposeExpressionToJson,
|
|
48
49
|
} from "../../common/serialization/json.js";
|
|
49
50
|
import { getFullyQualifiedTypeName } from "../../util/name.js";
|
|
50
51
|
import { canonicalizeHttpOperation } from "../operation.js";
|
|
@@ -250,13 +251,6 @@ function* emitRawServerOperation(
|
|
|
250
251
|
|
|
251
252
|
if (requiresJsonSerialization(ctx, module, body.type)) {
|
|
252
253
|
if (body.type.kind === "Model" && isArrayModelType(ctx.program, body.type)) {
|
|
253
|
-
const innerTypeName = emitTypeReference(
|
|
254
|
-
ctx,
|
|
255
|
-
body.type.indexer.value,
|
|
256
|
-
body.type,
|
|
257
|
-
module,
|
|
258
|
-
{ requireDeclaration: true },
|
|
259
|
-
);
|
|
260
254
|
yield ` const __arrayBody = JSON.parse(body);`;
|
|
261
255
|
yield ` if (!Array.isArray(__arrayBody)) {`;
|
|
262
256
|
yield ` ${names.ctx}.errorHandlers.onInvalidRequest(`;
|
|
@@ -266,16 +260,8 @@ function* emitRawServerOperation(
|
|
|
266
260
|
yield ` );`;
|
|
267
261
|
yield ` return reject();`;
|
|
268
262
|
yield ` }`;
|
|
269
|
-
value = `__arrayBody
|
|
263
|
+
value = transposeExpressionFromJson(ctx, body.type, `__arrayBody`, module);
|
|
270
264
|
} else if (body.type.kind === "Model" && isRecordModelType(ctx.program, body.type)) {
|
|
271
|
-
const innerTypeName = emitTypeReference(
|
|
272
|
-
ctx,
|
|
273
|
-
body.type.indexer.value,
|
|
274
|
-
body.type,
|
|
275
|
-
module,
|
|
276
|
-
{ requireDeclaration: true },
|
|
277
|
-
);
|
|
278
|
-
|
|
279
265
|
yield ` const __recordBody = JSON.parse(body);`;
|
|
280
266
|
yield ` if (typeof __recordBody !== "object" || __recordBody === null) {`;
|
|
281
267
|
yield ` ${names.ctx}.errorHandlers.onInvalidRequest(`;
|
|
@@ -285,11 +271,11 @@ function* emitRawServerOperation(
|
|
|
285
271
|
yield ` );`;
|
|
286
272
|
yield ` return reject();`;
|
|
287
273
|
yield ` }`;
|
|
288
|
-
value =
|
|
274
|
+
value = transposeExpressionFromJson(ctx, body.type, `__recordBody`, module);
|
|
289
275
|
} else if (body.type.kind === "Scalar") {
|
|
290
276
|
value = transposeExpressionFromJson(ctx, body.type, `JSON.parse(body)`, module);
|
|
291
277
|
} else {
|
|
292
|
-
value = `${bodyTypeName}.fromJsonObject(JSON.parse(body))`;
|
|
278
|
+
value = `${bodyTypeName}.fromJsonObject(globalThis.JSON.parse(body))`;
|
|
293
279
|
}
|
|
294
280
|
} else {
|
|
295
281
|
value = `JSON.parse(body)`;
|
|
@@ -580,7 +566,7 @@ function* emitResultProcessingForType(
|
|
|
580
566
|
case "unknown":
|
|
581
567
|
yield `${names.ctx}.response.statusCode = 200;`;
|
|
582
568
|
yield `${names.ctx}.response.setHeader("content-type", "application/json");`;
|
|
583
|
-
yield `${names.ctx}.response.end(JSON.stringify(${names.result}));`;
|
|
569
|
+
yield `${names.ctx}.response.end(globalThis.JSON.stringify(${names.result}));`;
|
|
584
570
|
return;
|
|
585
571
|
case "never":
|
|
586
572
|
yield `return ${names.ctx}.errorHandlers.onInternalError(${names.ctx}, "Internal server error.");`;
|
|
@@ -647,9 +633,45 @@ function* emitResultProcessingForType(
|
|
|
647
633
|
altName: namer.getAltName("Body"),
|
|
648
634
|
requireDeclaration: true,
|
|
649
635
|
});
|
|
650
|
-
yield `${names.ctx}.response.end(JSON.stringify(${typeReference}.toJsonObject(${names.result}.${bodyCase.camelCase})))`;
|
|
636
|
+
yield `${names.ctx}.response.end(globalThis.JSON.stringify(${typeReference}.toJsonObject(${names.result}.${bodyCase.camelCase})))`;
|
|
637
|
+
} else {
|
|
638
|
+
yield `${names.ctx}.response.end(globalThis.JSON.stringify(${names.result}.${bodyCase.camelCase}));`;
|
|
639
|
+
}
|
|
640
|
+
} else if (isArrayModelType(ctx.program, target)) {
|
|
641
|
+
const itemType = target.indexer.value;
|
|
642
|
+
|
|
643
|
+
const serializationRequired = isSerializationRequired(
|
|
644
|
+
ctx,
|
|
645
|
+
module,
|
|
646
|
+
itemType,
|
|
647
|
+
"application/json",
|
|
648
|
+
);
|
|
649
|
+
requireSerialization(ctx, itemType, "application/json");
|
|
650
|
+
|
|
651
|
+
yield `${names.ctx}.response.setHeader("content-type", "application/json");`;
|
|
652
|
+
|
|
653
|
+
if (serializationRequired) {
|
|
654
|
+
yield `${names.ctx}.response.end(globalThis.JSON.stringify(${transposeExpressionToJson(ctx, target, names.result, module)}));`;
|
|
655
|
+
} else {
|
|
656
|
+
yield `${names.ctx}.response.end(globalThis.JSON.stringify(${names.result}));`;
|
|
657
|
+
}
|
|
658
|
+
} else if (isRecordModelType(ctx.program, target)) {
|
|
659
|
+
const itemType = target.indexer.value;
|
|
660
|
+
|
|
661
|
+
const serializationRequired = isSerializationRequired(
|
|
662
|
+
ctx,
|
|
663
|
+
module,
|
|
664
|
+
itemType,
|
|
665
|
+
"application/json",
|
|
666
|
+
);
|
|
667
|
+
requireSerialization(ctx, itemType, "application/json");
|
|
668
|
+
|
|
669
|
+
yield `${names.ctx}.response.setHeader("content-type", "application/json");`;
|
|
670
|
+
|
|
671
|
+
if (serializationRequired) {
|
|
672
|
+
yield `${names.ctx}.response.end(globalThis.JSON.stringify(${transposeExpressionToJson(ctx, target, names.result, module)}));`;
|
|
651
673
|
} else {
|
|
652
|
-
yield `${names.ctx}.response.end(JSON.stringify(${names.result}
|
|
674
|
+
yield `${names.ctx}.response.end(globalThis.JSON.stringify(${names.result}));`;
|
|
653
675
|
}
|
|
654
676
|
} else {
|
|
655
677
|
if (allMetadataIsRemoved) {
|
|
@@ -670,9 +692,9 @@ function* emitResultProcessingForType(
|
|
|
670
692
|
altName: namer.getAltName("Result"),
|
|
671
693
|
requireDeclaration: true,
|
|
672
694
|
});
|
|
673
|
-
yield `${names.ctx}.response.end(JSON.stringify(${typeReference}.toJsonObject(${names.result} as ${typeReference})));`;
|
|
695
|
+
yield `${names.ctx}.response.end(globalThis.JSON.stringify(${typeReference}.toJsonObject(${names.result} as ${typeReference})));`;
|
|
674
696
|
} else {
|
|
675
|
-
yield `${names.ctx}.response.end(JSON.stringify(${names.result}));`;
|
|
697
|
+
yield `${names.ctx}.response.end(globalThis.JSON.stringify(${names.result}));`;
|
|
676
698
|
}
|
|
677
699
|
}
|
|
678
700
|
}
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
getDiscriminator,
|
|
18
18
|
getMaxValue,
|
|
19
19
|
getMinValue,
|
|
20
|
+
isArrayModelType,
|
|
20
21
|
isNeverType,
|
|
21
22
|
isUnknownType,
|
|
22
23
|
} from "@typespec/compiler";
|
|
@@ -136,6 +137,7 @@ export interface SwitchCase {
|
|
|
136
137
|
export type Expression =
|
|
137
138
|
| BinaryOp
|
|
138
139
|
| UnaryOp
|
|
140
|
+
| IsArray
|
|
139
141
|
| TypeOf
|
|
140
142
|
| Literal
|
|
141
143
|
| VerbatimExpression
|
|
@@ -192,6 +194,17 @@ export interface UnaryOp {
|
|
|
192
194
|
operand: Expression;
|
|
193
195
|
}
|
|
194
196
|
|
|
197
|
+
/**
|
|
198
|
+
* An array test expression.
|
|
199
|
+
*/
|
|
200
|
+
export interface IsArray {
|
|
201
|
+
kind: "is-array";
|
|
202
|
+
/**
|
|
203
|
+
* The expression to test.
|
|
204
|
+
*/
|
|
205
|
+
expr: Expression;
|
|
206
|
+
}
|
|
207
|
+
|
|
195
208
|
/**
|
|
196
209
|
* A type-of operation.
|
|
197
210
|
*/
|
|
@@ -660,7 +673,14 @@ export function differentiateModelTypes(
|
|
|
660
673
|
const propertyRanges = new Map<RenderedPropertyName, Map<IntegerRange, Model>>();
|
|
661
674
|
const uniqueRanges = new Map<Model, Set<RenderedPropertyName>>();
|
|
662
675
|
|
|
676
|
+
let arrayVariant: Model | undefined = undefined;
|
|
677
|
+
|
|
663
678
|
for (const model of models) {
|
|
679
|
+
if (isArrayModelType(ctx.program, model) && model.properties.size === 0 && !arrayVariant) {
|
|
680
|
+
arrayVariant = model;
|
|
681
|
+
continue;
|
|
682
|
+
}
|
|
683
|
+
|
|
664
684
|
const props = new Set<string>();
|
|
665
685
|
|
|
666
686
|
for (const prop of getAllProperties(model).filter(options.filter)) {
|
|
@@ -758,6 +778,16 @@ export function differentiateModelTypes(
|
|
|
758
778
|
|
|
759
779
|
let defaultCase: CodeTree | undefined = options.else;
|
|
760
780
|
|
|
781
|
+
if (arrayVariant) {
|
|
782
|
+
branches.push({
|
|
783
|
+
condition: {
|
|
784
|
+
kind: "is-array",
|
|
785
|
+
expr: SUBJECT,
|
|
786
|
+
},
|
|
787
|
+
body: { kind: "result", type: arrayVariant },
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
|
|
761
791
|
for (const [model, unique] of uniqueProps) {
|
|
762
792
|
const literals = uniqueLiterals.get(model);
|
|
763
793
|
const ranges = uniqueRanges.get(model);
|
|
@@ -958,6 +988,8 @@ function writeExpression(ctx: JsContext, expression: Expression, options: CodeTr
|
|
|
958
988
|
)})`;
|
|
959
989
|
case "unary-op":
|
|
960
990
|
return `${expression.operator}(${writeExpression(ctx, expression.operand, options)})`;
|
|
991
|
+
case "is-array":
|
|
992
|
+
return `globalThis.Array.isArray(${writeExpression(ctx, expression.expr, options)})`;
|
|
961
993
|
case "typeof":
|
|
962
994
|
return `typeof (${writeExpression(ctx, expression.operand, options)})`;
|
|
963
995
|
case "literal":
|