@typespec/http-server-js
Version:
TypeSpec HTTP server code generator for JavaScript
81 lines • 3.47 kB
JavaScript
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license.
import { NoTarget } from "@typespec/compiler";
import { $ } from "@typespec/compiler/typekit";
import { completePendingDeclarations } from "../../ctx.js";
import { indent } from "../../util/iter.js";
import { createOrGetModuleForNamespace } from "../namespace.js";
import { emitTypeReference } from "../reference.js";
import { emitJsonSerialization, requiresJsonSerialization } from "./json.js";
export function isSerializableType(t) {
return t.kind === "Model" || t.kind === "Union" || t.kind === "Intrinsic" || t.kind === "Enum";
}
const _SERIALIZATIONS_MAP = new WeakMap();
export function requireSerialization(ctx, type, contentType) {
if (!isSerializableType(type))
return;
// Ignore array and record types
if ($(ctx.program).array.is(type) || $(ctx.program).record.is(type)) {
return requireSerialization(ctx, type.indexer.value, contentType);
}
let serializationsForType = _SERIALIZATIONS_MAP.get(type);
if (!serializationsForType) {
serializationsForType = new Set();
_SERIALIZATIONS_MAP.set(type, serializationsForType);
}
serializationsForType.add(contentType);
ctx.serializations.add(type);
}
export function emitSerialization(ctx) {
completePendingDeclarations(ctx);
const serializationContext = {
...ctx,
};
while (!ctx.serializations.isEmpty()) {
const type = ctx.serializations.take();
const serializations = _SERIALIZATIONS_MAP.get(type);
const requiredSerializations = new Set([...serializations].filter((serialization) => {
const isSynthetic = ctx.syntheticNames.has(type) || !type.namespace;
const module = isSynthetic
? ctx.syntheticModule
: createOrGetModuleForNamespace(ctx, type.namespace);
return isSerializationRequired(ctx, module, type, serialization);
}));
if (requiredSerializations.size > 0) {
emitSerializationsForType(serializationContext, type, serializations);
}
}
}
export function isSerializationRequired(ctx, module, type, serialization) {
switch (serialization) {
case "application/json": {
return requiresJsonSerialization(ctx, module, type);
}
default:
throw new Error(`Unreachable: serialization content type ${serialization}`);
}
}
function emitSerializationsForType(ctx, type, serializations) {
const isSynthetic = ctx.syntheticNames.has(type) || !type.namespace;
const module = isSynthetic
? ctx.syntheticModule
: createOrGetModuleForNamespace(ctx, type.namespace);
const typeName = emitTypeReference(ctx, type, NoTarget, module);
const serializationCode = [`export const ${typeName} = {`];
for (const serialization of serializations) {
serializationCode.push(...indent(emitSerializationForType(ctx, type, serialization, module, typeName)));
}
serializationCode.push("} as const;");
module.declarations.push(serializationCode);
}
function* emitSerializationForType(ctx, type, contentType, module, typeName) {
switch (contentType) {
case "application/json": {
yield* emitJsonSerialization(ctx, type, module, typeName);
break;
}
default:
throw new Error(`Unreachable: serialization content type ${contentType}`);
}
}
//# sourceMappingURL=index.js.map