@typespec/openapi3
Version:
TypeSpec library for emitting OpenAPI 3.0 and OpenAPI 3.1 from the TypeSpec REST protocol binding and converting OpenAPI3 to TypeSpec
137 lines • 4.19 kB
JavaScript
import { getEncode, isTemplateDeclaration, serializeValueAsJson, } from "@typespec/compiler";
import { createDiagnostic } from "./lib.js";
/**
* Checks if two objects are deeply equal.
*
* Does not support cycles. Intended to be used only on plain data that can
* be directly represented in JSON.
*/
export function deepEquals(left, right) {
if (left === right) {
return true;
}
if (left === null || right === null || typeof left !== "object" || typeof right !== "object") {
return false;
}
if (Array.isArray(left)) {
return Array.isArray(right) ? arrayEquals(left, right, deepEquals) : false;
}
return mapEquals(new Map(Object.entries(left)), new Map(Object.entries(right)), deepEquals);
}
/**
* Check if two arrays have the same elements.
*
* @param equals Optional callback for element equality comparison.
* Default is to compare by identity using `===`.
*/
export function arrayEquals(left, right, equals = (x, y) => x === y) {
if (left === right) {
return true;
}
if (left.length !== right.length) {
return false;
}
for (let i = 0; i < left.length; i++) {
if (!equals(left[i], right[i])) {
return false;
}
}
return true;
}
/**
* Check if two maps have the same entries.
*
* @param equals Optional callback for value equality comparison.
* Default is to compare by identity using `===`.
*/
export function mapEquals(left, right, equals = (x, y) => x === y) {
if (left === right) {
return true;
}
if (left.size !== right.size) {
return false;
}
for (const [key, value] of left) {
if (!right.has(key) || !equals(value, right.get(key))) {
return false;
}
}
return true;
}
/**
* Check if argument is not undefined.
*/
export function isDefined(arg) {
return arg !== undefined;
}
export function isSharedHttpOperation(operation) {
return operation.kind === "shared";
}
export function isStdType(program, type) {
return program.checker.isStdType(type);
}
export function isLiteralType(type) {
return type.kind === "Boolean" || type.kind === "String" || type.kind === "Number";
}
export function literalType(type) {
switch (type.kind) {
case "String":
return "string";
case "Number":
return "number";
case "Boolean":
return "boolean";
}
}
export function includeDerivedModel(model) {
return (!isTemplateDeclaration(model) &&
(model.templateMapper?.args === undefined ||
model.templateMapper.args?.length === 0 ||
model.derivedModels.length > 0));
}
export function isScalarExtendsBytes(type) {
if (type.kind !== "Scalar") {
return false;
}
let current = type;
while (current) {
if (current.name === "bytes") {
return true;
}
current = current.baseScalar;
}
return false;
}
export function getDefaultValue(program, defaultType, modelProperty) {
return serializeValueAsJson(program, defaultType, modelProperty);
}
export function isBytesKeptRaw(program, type) {
return type.kind === "Scalar" && type.name === "bytes" && getEncode(program, type) === undefined;
}
export function ensureValidComponentFixedFieldKey(program, type, oldKey) {
if (isValidComponentFixedFieldKey(oldKey))
return oldKey;
reportInvalidKey(program, type, oldKey);
return createValidKey(oldKey);
}
function isValidComponentFixedFieldKey(key) {
const validPattern = /^[a-zA-Z0-9.\-_]+$/;
return validPattern.test(key);
}
function reportInvalidKey(program, type, key) {
const diagnostic = createDiagnostic({
code: "invalid-component-fixed-field-key",
format: {
value: key,
},
target: type,
});
return program.reportDiagnostic(diagnostic);
}
function createValidKey(invalidKey) {
return invalidKey.replace(/[^a-zA-Z0-9.\-_]/g, "_");
}
export function isHttpParameterProperty(httpProperty) {
return ["header", "query", "path", "cookie"].includes(httpProperty.kind);
}
//# sourceMappingURL=util.js.map