@typespec/http-server-js
Version:
TypeSpec HTTP server code generator for JavaScript
284 lines • 8.47 kB
TypeScript
import { BooleanLiteral, EnumMember, Model, ModelProperty, NullType, NumericLiteral, Scalar, StringLiteral, Type, Union, UnknownType, VoidType } from "@typespec/compiler";
import { JsContext, Module } from "../ctx.js";
/**
* A tree structure representing a body of TypeScript code.
*/
export type CodeTree = Result | IfChain | Switch | Verbatim;
export type JsLiteralType = StringLiteral | BooleanLiteral | NumericLiteral | EnumMember;
/**
* A TypeSpec type that is precise, i.e. the type of a single value.
*/
export type PreciseType = Scalar | Model | JsLiteralType | VoidType | NullType;
/**
* Determines if `t` is a precise type.
* @param t - the type to test
* @returns true if `t` is precise, false otherwise.
*/
export declare function isPreciseType(t: Type): t is PreciseType;
/**
* An if-chain structure in the CodeTree DSL. This represents a cascading series of if-else-if statements with an optional
* final `else` branch.
*/
export interface IfChain {
kind: "if-chain";
branches: IfBranch[];
else?: CodeTree;
}
/**
* A branch in an if-chain.
*/
export interface IfBranch {
/**
* A condition to test for this branch.
*/
condition: Expression;
/**
* The body of this branch, to be executed if the condition is true.
*/
body: CodeTree;
}
/**
* A node in the code tree indicating that a precise type has been determined.
*/
export interface Result {
kind: "result";
type: PreciseType | UnknownType;
}
/**
* A switch structure in the CodeTree DSL.
*/
export interface Switch {
kind: "switch";
/**
* The expression to switch on.
*/
condition: Expression;
/**
* The cases to test for.
*/
cases: SwitchCase[];
/**
* The default case, if any.
*/
default?: CodeTree;
}
/**
* A verbatim code block.
*/
export interface Verbatim {
kind: "verbatim";
body: Iterable<string> | (() => Iterable<string>);
}
/**
* A case in a switch statement.
*/
export interface SwitchCase {
/**
* The value to test for in this case.
*/
value: Expression;
/**
* The body of this case.
*/
body: CodeTree;
}
/**
* An expression in the CodeTree DSL.
*/
export type Expression = BinaryOp | UnaryOp | IsArray | TypeOf | Literal | VerbatimExpression | SubjectReference | ModelPropertyReference | InRange;
/**
* A binary operation.
*/
export interface BinaryOp {
kind: "binary-op";
/**
* The operator to apply. This operation may be sensitive to the order of the left and right expressions.
*/
operator: "===" | "!==" | "<" | "<=" | ">" | ">=" | "+" | "-" | "*" | "/" | "%" | "&&" | "||" | "instanceof" | "in";
/**
* The left-hand-side operand.
*/
left: Expression;
/**
* The right-hand-side operand.
*/
right: Expression;
}
/**
* A unary operation.
*/
export interface UnaryOp {
kind: "unary-op";
/**
* The operator to apply.
*/
operator: "!" | "-";
/**
* The operand to apply the operator to.
*/
operand: Expression;
}
/**
* An array test expression.
*/
export interface IsArray {
kind: "is-array";
/**
* The expression to test.
*/
expr: Expression;
}
/**
* A type-of operation.
*/
export interface TypeOf {
kind: "typeof";
/**
* The operand to apply the `typeof` operator to.
*/
operand: Expression;
}
/**
* A literal JavaScript value. The value will be converted to the text of an expression that will yield the same value.
*/
export interface Literal {
kind: "literal";
/**
* The value of the literal.
*/
value: LiteralValue;
}
/**
* A verbatim expression, written as-is with no modification.
*/
export interface VerbatimExpression {
kind: "verbatim";
/**
* The exact text of the expression.
*/
text: string;
}
/**
* A reference to the "subject" of the code tree.
*
* The "subject" is a special expression denoting an input value.
*/
export interface SubjectReference {
kind: "subject";
}
/**
* A reference to a model property. Model property references are rendered by the `referenceModelProperty` function in the
* options given to `writeCodeTree`, allowing the caller to define how model properties are stored.
*/
export interface ModelPropertyReference {
kind: "model-property";
property: ModelProperty;
}
/**
* A check to see if a value is in an integer range.
*/
export interface InRange {
kind: "in-range";
/**
* The expression to check.
*/
expr: Expression;
/**
* The range to check against.
*/
range: IntegerRange;
}
/**
* A literal value that can be used in a JavaScript expression.
*/
export type LiteralValue = string | number | boolean | bigint;
/**
* Differentiates the variants of a union type. This function returns a CodeTree that will test an input "subject" and
* determine which of the cases it matches.
*
* Compared to `differentiateTypes`, this function is specialized for union types, and will consider union
* discriminators first, then delegate to `differentiateTypes` for the remaining cases.
*
* @param ctx
* @param type
*/
export declare function differentiateUnion(ctx: JsContext, module: Module, union: Union, renderPropertyName?: (prop: ModelProperty) => string): CodeTree;
/**
* Differentiates a set of input types. This function returns a CodeTree that will test an input "subject" and determine
* which of the cases it matches, executing the corresponding code block.
*
* @param ctx - The emitter context.
* @param cases - A map of cases to differentiate to their respective code blocks.
* @returns a CodeTree to use with `writeCodeTree`
*/
export declare function differentiateTypes(ctx: JsContext, module: Module, cases: Set<PreciseType>, renderPropertyName?: (prop: ModelProperty) => string): CodeTree;
/**
* An integer range, inclusive.
*/
type IntegerRange = [number, number];
/**
* Optional paramters for model differentiation.
*/
interface DifferentiateModelOptions {
/**
* A function that converts a model property reference over the subject to a string.
*
* Default: `(prop) => prop.name`
*/
renderPropertyName?: (prop: ModelProperty) => string;
/**
* A filter function that determines which properties to consider for differentiation.
*
* Default: `() => true`
*/
filter?: (prop: ModelProperty) => boolean;
/**
* The default case to use if no other cases match.
*
* Default: undefined.
*/
else?: CodeTree | undefined;
}
/**
* Differentiate a set of model types based on their properties. This function returns a CodeTree that will test an input
* "subject" and determine which of the cases it matches, executing the corresponding code block.
*
* @param ctx - The emitter context.
* @param models - A map of models to differentiate to their respective code blocks.
* @param renderPropertyName - A function that converts a model property reference over the subject to a string.
* @returns a CodeTree to use with `writeCodeTree`
*/
export declare function differentiateModelTypes(ctx: JsContext, module: Module, models: Set<Model>, options?: DifferentiateModelOptions): CodeTree;
/**
* Options for the `writeCodeTree` function.
*/
export interface CodeTreeOptions {
/**
* The subject expression to use in the code tree.
*
* This text is used whenever a `SubjectReference` is encountered in the code tree, allowing the caller to specify
* how the subject is stored and referenced.
*/
subject: string;
/**
* A function that converts a model property to a string reference.
*
* This function is used whenever a `ModelPropertyReference` is encountered in the code tree, allowing the caller to
* specify how model properties are stored and referenced.
*/
referenceModelProperty: (p: ModelProperty) => string;
/**
* Renders a result when encountered in the code tree.
*/
renderResult: (type: PreciseType | UnknownType) => Iterable<string>;
}
/**
* Writes a code tree to text, given a set of options.
*
* @param ctx - The emitter context.
* @param tree - The code tree to write.
* @param options - The options to use when writing the code tree.
*/
export declare function writeCodeTree(ctx: JsContext, tree: CodeTree, options: CodeTreeOptions): Iterable<string>;
export {};
//# sourceMappingURL=differentiate.d.ts.map