Move OpenAPI2 types into @azure-tools/openapi library (#4465)

This commit is contained in:
Timothee Guerin 2022-03-14 09:15:13 -07:00 коммит произвёл GitHub
Родитель 82887f1ed0
Коммит bdf3f0ca4a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
60 изменённых файлов: 833 добавлений и 954 удалений

Просмотреть файл

@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@autorest/core",
"comment": "Uptake change in typing in openapi library",
"type": "minor"
}
],
"packageName": "@autorest/core",
"email": "tiguerin@microsoft.com"
}

Просмотреть файл

@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@autorest/modelerfour",
"comment": "Uptake change in typing in openapi library",
"type": "minor"
}
],
"packageName": "@autorest/modelerfour",
"email": "tiguerin@microsoft.com"
}

Просмотреть файл

@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@azure-tools/oai2-to-oai3",
"comment": "Extract OpenAPI2 types into @azure-tools/openapi package",
"type": "minor"
}
],
"packageName": "@azure-tools/oai2-to-oai3",
"email": "tiguerin@microsoft.com"
}

Просмотреть файл

@ -0,0 +1,16 @@
{
"changes": [
{
"packageName": "@azure-tools/openapi",
"comment": "Add `/v2` scope to load OpenAPI2 schema types.",
"type": "minor"
},
{
"packageName": "@azure-tools/openapi",
"comment": "Update OpenAPI 3.0 types to be more accurate.",
"type": "minor"
}
],
"packageName": "@azure-tools/openapi",
"email": "tiguerin@microsoft.com"
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -21,4 +21,7 @@ const config = {
testEnvironment: "node",
};
// Disable ts-jest warning because we are using alpha version of jest 28.x to resolve this issue https://github.com/facebook/jest/issues/9771
process.env.TS_JEST_DISABLE_VER_CHECKER = "1";
module.exports = config;

Просмотреть файл

@ -67,7 +67,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"jsonpath": "1.0.0",
"mkdirp": "~0.5.1",
"prettier": "~2.3.1",

Просмотреть файл

@ -51,7 +51,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"lodash": "~4.17.20",
"prettier": "~2.3.1",
"rimraf": "^3.0.2",

Просмотреть файл

@ -80,7 +80,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"jsonpath": "1.0.0",
"lodash": "~4.17.20",
"mkdirp": "~0.5.1",

Просмотреть файл

@ -30,7 +30,7 @@ function cleanAllOfForSchema(schema: Schema) {
}
// otherwise, copy this schema stuff into the schema
for (const [key, value] of Object.entries(aSchema)) {
schema[key] = value;
schema[key as any] = value;
}
return undefined;
})

Просмотреть файл

@ -31,7 +31,7 @@ export class ComponentKeyRenamer extends Transformer<any, oai.Model> {
// copy these over without worrying about moving things down to components.
default:
this.clone(targetParent, key, pointer, value);
this.clone(targetParent, key as any, pointer, value);
break;
}
}

Просмотреть файл

@ -55,14 +55,13 @@ export class ComponentsCleaner extends Transformer<any, oai.Model> {
switch (key) {
case "components":
{
const components =
<oai.Components>targetParent.components || this.newObject(targetParent, "components", pointer);
const components = targetParent.components || this.newObject(targetParent, "components", pointer);
this.visitComponents(components, children);
}
break;
default:
this.clone(targetParent, key, pointer, value);
this.clone(targetParent, key as any, pointer, value);
break;
}
}
@ -228,12 +227,12 @@ class UnsuedComponentFinder {
}
for (const item of arrayify(items)) {
if (item.$ref) {
if ("$ref" in item) {
const refParts = item.$ref.split("/");
const componentRefUid = refParts.pop();
const refType = refParts.pop() as keyof ComponentTracker;
if (
this.componentsToKeep[refType].has(componentRefUid) &&
this.componentsToKeep[refType].has(componentRefUid as string) &&
!this.componentsToKeep[containerType].has(currentComponentUid)
) {
this.componentsToKeep[containerType].add(currentComponentUid);

Просмотреть файл

@ -98,14 +98,14 @@ export class MultiAPIMerger extends Transformer<any, oai.Model> {
case "x-ms-paths":
// Merge paths and x-ms-paths together under paths.
if (!this.isSecondaryFile) {
const paths = <oai.PathItem>target.paths || this.newObject(target, "paths", pointer);
this.visitPaths(paths, children);
const paths = target.paths || this.newObject(target, "paths", pointer);
this.visitPaths(paths as any, children);
}
break;
case "components":
{
const components = <oai.Components>target.components || this.newObject(target, "components", pointer);
const components = target.components || this.newObject(target, "components", pointer);
this.visitComponents(components, children);
}
break;
@ -150,7 +150,7 @@ export class MultiAPIMerger extends Transformer<any, oai.Model> {
}
const docsMetadata =
(<oai.ExternalDocumentation>target.externalDocs)["x-ms-metadata"] ||
this.newArray(<oai.ExternalDocumentation>target.externalDocs, "x-ms-metadata", pointer);
this.newArray(<oai.ExternalDocumentation>target.externalDocs, "x-ms-metadata" as any, pointer);
docsMetadata.__push__({
value: cloneDeep(value),
pointer,
@ -169,8 +169,8 @@ export class MultiAPIMerger extends Transformer<any, oai.Model> {
default:
if (!this.isSecondaryFile) {
if (!target[key]) {
this.copy(target, key, pointer, value);
if (!target[key as any]) {
this.copy(target, key as any, pointer, value);
}
}
break;
@ -457,7 +457,7 @@ export class MultiAPIMerger extends Transformer<any, oai.Model> {
this.newObject(components, key, pointer);
}
this.visitComponent(key, components[key], children);
this.visitComponent(key, components[key] as any, children);
}
}

Просмотреть файл

@ -268,7 +268,7 @@ export class ProfileFilter extends Transformer<any, oai.Model> {
break;
default:
this.clone(targetParent, key, pointer, value);
this.clone(targetParent, key as any, pointer, value);
break;
}
}

Просмотреть файл

@ -7,7 +7,7 @@ const baseModel: oai3.Model = {
title: "Semantic Validation Unit Tests",
version: "1.0",
},
openApi: "3.0.0",
openapi: "3.0.0",
paths: {},
};

Просмотреть файл

@ -7,7 +7,7 @@ const baseModel: oai3.Model = {
title: "Semantic Validation Unit Tests",
version: "1.0",
},
openApi: "3.0.0",
openapi: "3.0.0",
paths: {},
};

Просмотреть файл

@ -7,7 +7,7 @@ const baseModel: oai3.Model = {
title: "Semantic Validation Unit Tests",
version: "1.0",
},
openApi: "3.0.0",
openapi: "3.0.0",
paths: {},
};

Просмотреть файл

@ -32,7 +32,7 @@ export class SubsetSchemaDeduplicator extends Transformer<any, oai.Model> {
// copy these over without worrying about moving things down to components.
default:
this.clone(targetParent, key, pointer, value);
this.clone(targetParent, key as any, pointer, value);
break;
}
}

Просмотреть файл

@ -4,7 +4,7 @@ import { OAI3Shaker } from "./tree-shaker";
const createTestModel = (model: Partial<Model>): Model => {
return {
openApi: "3.0.0",
openapi: "3.0.0",
paths: {},
info: {
title: "Test spec",

Просмотреть файл

@ -43,13 +43,13 @@ export class ApiVersionParameterHandler extends Transformer<any, oai.Model> {
case "paths":
{
const paths = <oai.PathItem>targetParent.paths || this.newObject(targetParent, "paths", pointer);
this.visitPaths(paths, children);
const paths = targetParent.paths || this.newObject(targetParent, "paths", pointer);
this.visitPaths(paths as any, children);
}
break;
default:
this.clone(targetParent, key, pointer, value);
this.clone(targetParent, key as any, pointer, value);
break;
}
}

Просмотреть файл

@ -61,7 +61,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"lodash": "~4.17.20",
"prettier": "~2.3.1",
"recursive-diff": "~1.0.6",

Просмотреть файл

@ -857,7 +857,7 @@ export class ModelerFour {
maxProperties: schema.maxProperties ? Number(schema.maxProperties) : undefined,
language: {
default: {
summary: schema.summary || schema.title,
summary: schema.title,
},
},
}),
@ -866,14 +866,13 @@ export class ModelerFour {
// cache this now before we accidentally recurse on this type.
this.schemaCache.set(schema, objectSchema);
for (const [propertyName, propertyDeclaration] of Object.entries(schema.properties ?? {})) {
const property = this.resolve(propertyDeclaration);
this.use(<OpenAPI.Refable<OpenAPI.Schema>>propertyDeclaration, (pSchemaName, pSchema) => {
const pType = this.processSchema(pSchemaName || `type·for·${propertyName}`, pSchema);
const prop = objectSchema.addProperty(
new Property(
this.interpret.getPreferredName(propertyDeclaration, propertyName),
propertyDeclaration.description ||
this.interpret.getDescription(pType.language.default.description, property),
this.interpret.getDescription(pType.language.default.description, pSchema),
pType,
{
readOnly: propertyDeclaration.readOnly || pSchema.readOnly,
@ -881,8 +880,8 @@ export class ModelerFour {
required: schema.required ? schema.required.indexOf(propertyName) > -1 : undefined,
serializedName: propertyName,
isDiscriminator: discriminatorProperty === propertyName ? true : undefined,
extensions: this.interpret.getExtensionProperties(property, propertyDeclaration),
clientDefaultValue: this.interpret.getClientDefault(property.instance, propertyDeclaration),
extensions: this.interpret.getExtensionProperties(pSchema, propertyDeclaration),
clientDefaultValue: this.interpret.getClientDefault(pSchema, propertyDeclaration),
},
),
);
@ -1487,7 +1486,7 @@ export class ModelerFour {
const pSchema =
requestBodyGroup.type === KnownMediaType.Text
? this.stringSchema
: this.processBinarySchema(requestSchema?.name || "upload", requestSchema || <OpenAPI.Schema>{});
: this.processBinarySchema((requestSchema as any)?.name || "upload", requestSchema || <OpenAPI.Schema>{});
// add a stream parameter for the body
httpRequest.addParameter(
new Parameter(bodyName, this.interpret.getDescription("", body?.instance || {}), pSchema, {
@ -1568,14 +1567,13 @@ export class ModelerFour {
// but we must turn them back into operation parameters so that code
// generators will generate them as method parameters.
for (const [propertyName, propertyDeclaration] of Object.entries(requestSchema.properties ?? {})) {
const property = this.resolve(propertyDeclaration);
this.use(<OpenAPI.Refable<OpenAPI.Schema>>propertyDeclaration, (pSchemaName, pSchema) => {
const pType = this.processSchema(pSchemaName || `type·for·${propertyName}`, pSchema);
httpRequest.addParameter(
new Parameter(
propertyName,
propertyDeclaration.description ||
this.interpret.getDescription(pType.language.default.description, property),
this.interpret.getDescription(pType.language.default.description, pSchema),
pType,
{
schema: pType,
@ -1605,7 +1603,7 @@ export class ModelerFour {
});
}
} else {
const pSchema = this.processSchema(requestSchema?.name || "requestBody", requestSchema ?? {});
const pSchema = this.processSchema((requestSchema as any)?.name || "requestBody", requestSchema ?? {});
// Track the usage of this schema as an input with media type
this.trackSchemaUsage(pSchema, { usage: [SchemaContext.Input], serializationFormats: [kmt] });
@ -1618,7 +1616,7 @@ export class ModelerFour {
{
extensions: this.interpret.getExtensionProperties(body.instance),
required: !!body.instance.required,
nullable: requestSchema?.instance?.nullable,
nullable: requestSchema?.nullable,
protocol: {
http: new HttpParameter(ParameterLocation.Body, {
style: <SerializationStyle>(<any>kmt),
@ -2045,7 +2043,7 @@ export class ModelerFour {
implementation,
extensions: this.interpret.getExtensionProperties(parameter),
deprecated: this.interpret.getDeprecation(parameter),
nullable: parameter.nullable || schema.nullable,
nullable: (parameter as any).nullable || schema.nullable,
protocol: {
http: new HttpParameter(
parameter.in,

Просмотреть файл

@ -5,7 +5,7 @@ import { Interpretations } from "./interpretations";
import { SecurityProcessor } from "./security-processor";
const baseOpenapiSpec = {
openApi: "3.0.0",
openapi: "3.0.0",
info: {
title: "Base spec",
version: "1.0",

Просмотреть файл

@ -187,10 +187,10 @@ export class DuplicateSchemaMerger {
* @returns Schema to keep and list of schema to remove.
*/
private findSchemaToRemove(
spec: oai3.Model,
spec: oai3.OpenAPI3Document,
schemas: DereferencedSchema[],
): { keep: DereferencedSchema; remove: DereferencedSchema[] } {
const nonRefSchema = schemas.find((x) => spec.components?.schemas?.[x.key].$ref === undefined);
const nonRefSchema = schemas.find((x) => (spec.components?.schemas?.[x.key] as any).$ref === undefined);
if (nonRefSchema) {
return { keep: nonRefSchema, remove: schemas.filter((x) => x.key !== nonRefSchema.key) };
} else {

Просмотреть файл

@ -206,7 +206,7 @@ export class QualityPreChecker {
continue;
}
const $ref = schema?.allOf?.[0]?.$ref;
const $ref = (schema?.allOf?.[0] as any)?.$ref;
const text = JSON.stringify(this.input);
this.input = JSON.parse(text.replace(new RegExp(`"\\#\\/components\\/schemas\\/${key}"`, "g"), `"${$ref}"`));

Просмотреть файл

@ -79,7 +79,7 @@ describe("Prechecker", () => {
expect(schemas["SiblingSchema"]).toBeUndefined();
expect(schemas["MainSchema"]).not.toBeUndefined();
const mainSchema: Schema = schemas["MainSchema"] as any;
expect(mainSchema.properties?.name.type).toEqual("string");
expect((mainSchema.properties?.name as any).type).toEqual("string");
});
describe("Remove child types with no additional properties", () => {

Просмотреть файл

@ -48,7 +48,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"rimraf": "^3.0.2",
"source-map-support": "^0.5.19",
"ts-jest": "^27.0.3",

Просмотреть файл

@ -39,7 +39,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"rimraf": "^3.0.2",
"typescript": "~4.4.2"
},

Просмотреть файл

@ -41,7 +41,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"rimraf": "^3.0.2",
"ts-jest": "^27.0.3",
"typescript": "~4.4.2"

Просмотреть файл

@ -48,7 +48,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"rimraf": "^3.0.2",
"ts-jest": "^27.0.3",
"typescript": "~4.4.2"

Просмотреть файл

@ -47,7 +47,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"rimraf": "^3.0.2",
"typescript": "~4.4.2"
},

Просмотреть файл

@ -70,7 +70,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"mkdirp": "~0.5.1",
"source-map-support": "^0.5.19",
"typescript": "~4.4.2"

Просмотреть файл

@ -38,7 +38,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"rimraf": "^3.0.2",
"typescript": "~4.4.2"
},

Просмотреть файл

@ -38,7 +38,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"rimraf": "^3.0.2",
"typescript": "~4.4.2"
},

Просмотреть файл

@ -48,7 +48,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"rimraf": "^3.0.2",
"source-map-support": "^0.5.19",
"ts-jest": "^27.0.3",

Просмотреть файл

@ -1,4 +1,4 @@
import { OpenAPI2Operation } from "./oai2";
import { OpenAPI2Operation } from "@azure-tools/openapi/v2";
/**
* Resolve the list of content types produced by an operation.

Просмотреть файл

@ -11,15 +11,7 @@ import {
createMappingTree,
} from "@azure-tools/datastore";
import { JsonPointer, getFromJsonPointer, appendJsonPointer } from "@azure-tools/json";
import oai3, {
EncodingStyle,
HttpOperation,
includeXDashKeys,
JsonType,
PathItem,
SecurityType,
} from "@azure-tools/openapi";
import { resolveOperationConsumes, resolveOperationProduces } from "./content-type-utils";
import { includeXDashKeys, isExtensionKey, PathReference, Refable } from "@azure-tools/openapi";
import {
OpenAPI2Document,
OpenAPI2ResponseHeader,
@ -29,7 +21,17 @@ import {
OpenAPI2FormDataParameter,
HttpMethod,
OpenAPI2Parameter,
} from "./oai2";
} from "@azure-tools/openapi/v2";
import oai3, {
OpenAPI3Document,
EncodingStyle,
HttpOperation,
JsonType,
PathItem,
SecurityType,
OAuth2SecurityScheme,
} from "@azure-tools/openapi/v3";
import { resolveOperationConsumes, resolveOperationProduces } from "./content-type-utils";
import { cleanElementName, convertOai2RefToOai3, parseOai2Ref } from "./refs-utils";
import { ResolveReferenceFn } from "./runner";
import { statusCodes } from "./status-codes";
@ -70,7 +72,7 @@ export interface ConverterLogger {
}
export class Oai2ToOai3 {
public generated: MappingTreeObject<oai3.Model>;
public generated: MappingTreeObject<OpenAPI3Document>;
public mappings: PathMapping[] = [];
constructor(
@ -291,127 +293,146 @@ export class Oai2ToOai3 {
}
}
}
private async visitParameter(
parameterTarget: MappingTreeObject<Refable<oai3.Parameter>>,
parameterValue: any,
sourcePointer: string,
parameterItemMembers: () => Iterable<Node>,
) {
if (this.isTargetReference(parameterTarget, parameterValue)) {
return this.copyRef(parameterTarget, parameterValue, sourcePointer);
} else {
await this.visitParameterDefinition(parameterTarget, parameterValue, sourcePointer, parameterItemMembers);
}
}
private isTargetReference<I, T>(
target: MappingTreeObject<Refable<T>>,
value: Refable<I>,
): target is MappingTreeObject<PathReference> {
return "$ref" in value;
}
private async copyRef(target: MappingTreeObject<PathReference>, value: PathReference, sourcePointer: string) {
target.__set__("$ref", { value: await this.convertReferenceToOai3(value.$ref), sourcePointer });
}
private async visitParameterDefinition(
parameterTarget: MappingTreeObject<oai3.Parameter>,
parameterValue: any,
sourcePointer: string,
parameterItemMembers: () => Iterable<Node>,
) {
if ("$ref" in parameterValue) {
parameterTarget.__set__("$ref", { value: await this.convertReferenceToOai3(parameterValue.$ref), sourcePointer });
} else {
const parameterUnchangedProperties = ["name", "in", "description", "allowEmptyValue", "required"];
const parameterUnchangedProperties = ["name", "in", "description", "allowEmptyValue", "required"];
for (const key of parameterUnchangedProperties) {
if (parameterValue[key] !== undefined) {
parameterTarget.__set__(key, { value: parameterValue[key], sourcePointer });
}
for (const key of parameterUnchangedProperties) {
if (parameterValue[key] !== undefined) {
parameterTarget.__set__(key as any, { value: parameterValue[key], sourcePointer });
}
}
if (parameterValue["x-ms-skip-url-encoding"] !== undefined) {
if (parameterValue["x-ms-skip-url-encoding"] !== undefined) {
if (parameterValue.in === "query") {
parameterTarget.__set__("allowReserved", { value: true, sourcePointer });
} else {
parameterTarget.__set__("x-ms-skip-url-encoding", {
value: parameterValue["x-ms-skip-url-encoding"],
sourcePointer,
});
}
}
/**
* List of extension properties that shouldn't just be passed through.
*/
const extensionPropertiesCustom = new Set(["x-ms-skip-url-encoding", "x-ms-original", "x-ms-enum"]);
for (const key of includeXDashKeys(parameterValue)) {
if (parameterValue[key] !== undefined && !extensionPropertiesCustom.has(key)) {
parameterTarget.__set__(key, { value: parameterValue[key], sourcePointer });
}
}
// Collection Format
if (parameterValue.type === "array") {
parameterValue.collectionFormat = parameterValue.collectionFormat || "csv";
if (
parameterValue.collectionFormat === "csv" &&
(parameterValue.in === "query" || parameterValue.in === "cookie")
) {
parameterTarget.__set__("style", { value: EncodingStyle.Form, sourcePointer });
}
if (
parameterValue.collectionFormat === "csv" &&
(parameterValue.in === "path" || parameterValue.in === "header")
) {
parameterTarget.__set__("style", { value: EncodingStyle.Simple, sourcePointer });
}
if (parameterValue.collectionFormat === "ssv") {
if (parameterValue.in === "query") {
parameterTarget.__set__("allowReserved", { value: true, sourcePointer });
} else {
parameterTarget.__set__("x-ms-skip-url-encoding", {
value: parameterValue["x-ms-skip-url-encoding"],
sourcePointer,
});
parameterTarget.__set__("style", { value: EncodingStyle.SpaceDelimited, sourcePointer });
}
}
/**
* List of extension properties that shouldn't just be passed through.
*/
const extensionPropertiesCustom = new Set(["x-ms-skip-url-encoding", "x-ms-original", "x-ms-enum"]);
for (const key of includeXDashKeys(parameterValue)) {
if (parameterValue[key] !== undefined && !extensionPropertiesCustom.has(key)) {
parameterTarget.__set__(key, { value: parameterValue[key], sourcePointer });
if (parameterValue.collectionFormat === "pipes") {
if (parameterValue.in === "query") {
parameterTarget.__set__("style", { value: EncodingStyle.PipeDelimited, sourcePointer });
}
}
// Collection Format
if (parameterValue.type === "array") {
parameterValue.collectionFormat = parameterValue.collectionFormat || "csv";
if (
parameterValue.collectionFormat === "csv" &&
(parameterValue.in === "query" || parameterValue.in === "cookie")
) {
parameterTarget.__set__("style", { value: EncodingStyle.Form, sourcePointer });
}
if (
parameterValue.collectionFormat === "csv" &&
(parameterValue.in === "path" || parameterValue.in === "header")
) {
parameterTarget.__set__("style", { value: EncodingStyle.Simple, sourcePointer });
}
if (parameterValue.collectionFormat === "ssv") {
if (parameterValue.in === "query") {
parameterTarget.__set__("style", { value: EncodingStyle.SpaceDelimited, sourcePointer });
}
}
if (parameterValue.collectionFormat === "pipes") {
if (parameterValue.in === "query") {
parameterTarget.__set__("style", { value: EncodingStyle.PipeDelimited, sourcePointer });
}
}
if (parameterValue.collectionFormat === "multi") {
parameterTarget.__set__("style", { value: EncodingStyle.Form, sourcePointer });
parameterTarget.__set__("explode", { value: true, sourcePointer });
}
// tsv is no longer supported in OAI3, but we still need to support this.
if (parameterValue.collectionFormat === "tsv") {
parameterTarget.__set__("style", { value: EncodingStyle.TabDelimited, sourcePointer });
}
if (parameterValue.collectionFormat === "multi") {
parameterTarget.__set__("style", { value: EncodingStyle.Form, sourcePointer });
parameterTarget.__set__("explode", { value: true, sourcePointer });
}
if (parameterTarget.schema === undefined) {
parameterTarget.__set__("schema", this.newObject(sourcePointer));
// tsv is no longer supported in OAI3, but we still need to support this.
if (parameterValue.collectionFormat === "tsv") {
parameterTarget.__set__("style", { value: EncodingStyle.TabDelimited, sourcePointer });
}
}
const schema: MappingTreeObject<oai3.Schema> = parameterTarget.schema as any;
if (parameterTarget.schema === undefined) {
parameterTarget.__set__("schema", this.newObject(sourcePointer));
}
const schemaKeys = [
"maximum",
"exclusiveMaximum",
"minimum",
"exclusiveMinimum",
"maxLength",
"minLength",
"pattern",
"maxItems",
"minItems",
"uniqueItems",
"enum",
"x-ms-enum",
"multipleOf",
"default",
"format",
];
const schema: MappingTreeObject<oai3.Schema> = parameterTarget.schema as any;
for (const { key, childIterator, pointer: jsonPointer } of parameterItemMembers()) {
if (key === "schema") {
if (schema.items === undefined) {
schema.__set__("items", this.newObject(jsonPointer));
}
const schemaKeys = [
"maximum",
"exclusiveMaximum",
"minimum",
"exclusiveMinimum",
"maxLength",
"minLength",
"pattern",
"maxItems",
"minItems",
"uniqueItems",
"enum",
"x-ms-enum",
"multipleOf",
"default",
"format",
];
for (const { key, childIterator, pointer: jsonPointer } of parameterItemMembers()) {
if (key === "schema") {
if (schema.items === undefined) {
schema.__set__("items", this.newObject(jsonPointer));
}
await this.visitSchema(schema.items as any, parameterValue.items, childIterator);
} else if (schemaKeys.indexOf(key) !== -1) {
schema.__set__(key as any, { value: parameterValue[key], sourcePointer });
}
}
if (parameterValue.type !== undefined) {
schema.__set__("type", { value: parameterValue.type, sourcePointer });
}
if (parameterValue.items !== undefined) {
schema?.__set__("items", this.newObject(sourcePointer));
for (const { key, childIterator } of parameterItemMembers()) {
if (key === "items") {
await this.visitSchema(schema.items as any, parameterValue.items, childIterator);
} else if (schemaKeys.indexOf(key) !== -1) {
schema.__set__(key, { value: parameterValue[key], sourcePointer });
}
}
if (parameterValue.type !== undefined) {
schema.__set__("type", { value: parameterValue.type, sourcePointer });
}
if (parameterValue.items !== undefined) {
schema?.__set__("items", this.newObject(sourcePointer));
for (const { key, childIterator } of parameterItemMembers()) {
if (key === "items") {
await this.visitSchema(schema.items as any, parameterValue.items, childIterator);
}
}
}
}
@ -454,7 +475,7 @@ export class Oai2ToOai3 {
case "description":
case "name":
case "in":
securityScheme.__set__(key, { value, sourcePointer: pointer });
securityScheme.__set__(key as any, { value, sourcePointer: pointer });
break;
default:
await this.visitExtensions(securityScheme, key, value, pointer);
@ -470,7 +491,7 @@ export class Oai2ToOai3 {
break;
case "type":
securityScheme.__set__("type", { value: SecurityType.Http, sourcePointer: pointer });
securityScheme.__set__("scheme", { value: "basic", sourcePointer: pointer });
securityScheme.__set__("scheme" as any, { value: "basic", sourcePointer: pointer });
break;
default:
await this.visitExtensions(securityScheme, key, value, pointer);
@ -480,12 +501,13 @@ export class Oai2ToOai3 {
break;
case "oauth2":
{
const oauth2Scheme: MappingTreeObject<OAuth2SecurityScheme> = securityScheme as any;
if (v.description !== undefined) {
securityScheme.__set__("description", { value: v.description, sourcePointer });
oauth2Scheme.__set__("description", { value: v.description, sourcePointer });
}
securityScheme.__set__("type", { value: v.type, sourcePointer });
securityScheme.__set__("flows", this.newObject(sourcePointer));
oauth2Scheme.__set__("type", { value: v.type, sourcePointer });
oauth2Scheme.__set__("flows", this.newObject(sourcePointer));
let flowName = v.flow;
// convert flow names to OpenAPI 3 flow names
@ -497,22 +519,22 @@ export class Oai2ToOai3 {
flowName = "authorizationCode";
}
securityScheme.flows.__set__(flowName, this.newObject(sourcePointer));
oauth2Scheme.flows.__set__(flowName, this.newObject(sourcePointer));
let authorizationUrl;
let tokenUrl;
if (v.authorizationUrl) {
authorizationUrl = v.authorizationUrl.split("?")[0].trim() || "/";
securityScheme.flows[flowName].__set__("authorizationUrl", { value: authorizationUrl, sourcePointer });
oauth2Scheme.flows[flowName].__set__("authorizationUrl", { value: authorizationUrl, sourcePointer });
}
if (v.tokenUrl) {
tokenUrl = v.tokenUrl.split("?")[0].trim() || "/";
securityScheme.flows[flowName].__set__("tokenUrl", { value: tokenUrl, sourcePointer });
oauth2Scheme.flows[flowName].__set__("tokenUrl", { value: tokenUrl, sourcePointer });
}
const scopes = v.scopes || {};
securityScheme.flows[flowName].__set__("scopes", { value: scopes, sourcePointer });
oauth2Scheme.flows[flowName].__set__("scopes", { value: scopes, sourcePointer });
}
break;
}
@ -570,7 +592,7 @@ export class Oai2ToOai3 {
for (const { key, value, pointer, childIterator } of schemaItemMemebers()) {
switch (key) {
case "$ref":
target.__set__("$ref", { value: await this.convertReferenceToOai3(value), sourcePointer: pointer });
await this.copyRef(target as any, { $ref: value }, pointer);
break;
case "additionalProperties":
if (typeof value === "boolean") {
@ -579,7 +601,7 @@ export class Oai2ToOai3 {
} // false is assumed anyway in autorest.
} else {
target.__set__(key, this.newObject(pointer));
await this.visitSchema(target[key]!, value, childIterator);
await this.visitSchema(target[key]! as any, value, childIterator);
}
break;
case "required":
@ -612,7 +634,7 @@ export class Oai2ToOai3 {
break;
case "items":
target.__set__(key, this.newObject(pointer));
await this.visitSchema(target[key]!, value, childIterator);
await this.visitSchema(target[key]! as any, value, childIterator);
break;
case "properties":
target.__set__(key, this.newObject(pointer));
@ -665,7 +687,7 @@ export class Oai2ToOai3 {
}
}
private async visitAllOf(target: MappingTreeArray<oai3.Refable<oai3.Schema>>, allOfMembers: () => Iterable<Node>) {
private async visitAllOf(target: MappingTreeArray<Refable<oai3.Schema>>, allOfMembers: () => Iterable<Node>) {
for (const { key: index, value, pointer, childIterator } of allOfMembers()) {
target.__push__(this.newObject(pointer));
await this.visitSchema(target[index], value, childIterator);
@ -1009,7 +1031,7 @@ export class Oai2ToOai3 {
if (parameterValue.schema !== undefined) {
for (const { key, value, childIterator } of parameterItemMembers()) {
if (key === "schema") {
await this.visitSchema(requestBody.content[mimetype].schema!, value, childIterator);
await this.visitSchema(requestBody.content[mimetype].schema! as any, value, childIterator);
}
}
} else {
@ -1019,7 +1041,7 @@ export class Oai2ToOai3 {
// copy extensions in requestBody
for (const { key, pointer: fieldPointer, value } of parameterItemMembers()) {
if (key.startsWith("x-")) {
if (isExtensionKey(key)) {
if (!requestBody[key]) {
requestBody.__set__(key, { value: value, sourcePointer: fieldPointer });
}
@ -1096,7 +1118,7 @@ export class Oai2ToOai3 {
// copy extensions in target property
for (const { key, pointer: fieldPointer, value } of parameterItemMembers()) {
if (key.startsWith("x-")) {
if (isExtensionKey(key)) {
targetProperty.__set__(key, { value: value, sourcePointer: fieldPointer });
}
}
@ -1109,9 +1131,9 @@ export class Oai2ToOai3 {
) {
for (const { key, value, pointer, childIterator } of responsesItemMembers) {
target.__set__(key, this.newObject(pointer));
if (value.$ref) {
target[key].__set__("$ref", { value: await this.convertReferenceToOai3(value.$ref), sourcePointer: pointer });
} else if (key.startsWith("x-")) {
if (this.isTargetReference(target, value)) {
return this.copyRef(target, value, pointer);
} else if (isExtensionKey(key)) {
await this.visitExtensions(target[key], key, value, pointer);
} else {
await this.visitResponse(target[key], value, key, childIterator, pointer, produces);
@ -1181,13 +1203,13 @@ export class Oai2ToOai3 {
responseTarget.__set__("headers", this.newObject(sourcePointer));
for (const h in responseValue.headers) {
responseTarget.headers!.__set__(h, this.newObject(sourcePointer));
await this.visitHeader(responseTarget.headers![h]!, responseValue.headers[h], sourcePointer);
await this.visitHeader(responseTarget.headers![h]! as any, responseValue.headers[h], sourcePointer);
}
}
// copy extensions
for (const { key, pointer: fieldPointer, value } of responsesFieldMembers()) {
if (key.startsWith("x-") && responseTarget[key] === undefined) {
if (isExtensionKey(key) && responseTarget[key] === undefined) {
responseTarget.__set__(key, { value: value, sourcePointer: fieldPointer });
}
}
@ -1221,11 +1243,8 @@ export class Oai2ToOai3 {
headerValue: OpenAPI2ResponseHeader,
sourcePointer: string,
) {
if (headerValue.$ref) {
targetHeader.__set__("$ref", {
value: this.convertReferenceToOai3(headerValue.schema.$ref),
sourcePointer,
});
if (this.isTargetReference(targetHeader, headerValue)) {
return this.copyRef(targetHeader, headerValue.schema, sourcePointer);
} else {
if (headerValue.type && headerValue.schema === undefined) {
targetHeader.__set__("schema", this.newObject(sourcePointer));
@ -1238,10 +1257,10 @@ export class Oai2ToOai3 {
const schema: MappingTreeObject<oai3.Schema> = targetHeader.schema as any;
for (const { key, childIterator } of visit(headerValue)) {
if (key === "schema") {
await this.visitSchema(schema.items!, headerValue.items, childIterator);
await this.visitSchema(schema.items! as any, headerValue.items, childIterator);
} else if (this.parameterTypeProperties.includes(key) || this.arrayProperties.includes(key)) {
schema.__set__(key, { value: headerValue[key], sourcePointer });
} else if (key.startsWith("x-") && targetHeader[key] === undefined) {
schema.__set__(key as any, { value: headerValue[key], sourcePointer });
} else if (isExtensionKey(key) && targetHeader[key] === undefined) {
targetHeader.__set__(key, { value: headerValue[key], sourcePointer });
}
}
@ -1251,7 +1270,7 @@ export class Oai2ToOai3 {
}
if (headerValue.items && headerValue.items.collectionFormat) {
if (headerValue.collectionFormat === "csv") {
targetHeader.__set__("style", { value: "simple", sourcePointer });
targetHeader.__set__("style" as any, { value: "simple", sourcePointer });
}
if (headerValue.collectionFormat === "multi") {

Просмотреть файл

@ -1,7 +1,7 @@
import { DataHandle, PathMapping } from "@azure-tools/datastore";
import { getFromJsonPointer } from "@azure-tools/json";
import { ConverterDiagnostic, ConverterLogger, Oai2ToOai3 } from "../converter";
import { OpenAPI2Document } from "../oai2";
import { OpenAPI2Document } from "@azure-tools/openapi/v2";
import { loadInputFiles } from "./utils";
export interface OaiToOai3FileInput {

Просмотреть файл

@ -1,5 +1,5 @@
import { DataHandle } from "@azure-tools/datastore";
import { OpenAPI2Document } from "../oai2";
import { OpenAPI2Document } from "@azure-tools/openapi/v2";
import { OaiToOai3FileInput } from "./oai2-to-oai3-runner";
export async function loadInputFiles(inputFiles: DataHandle[]): Promise<OaiToOai3FileInput[]> {

Просмотреть файл

@ -1,8 +1,8 @@
import fs from "fs";
import { join } from "path";
import * as datastore from "@azure-tools/datastore";
import { OpenAPI2Document } from "@azure-tools/openapi/v2";
import { ConverterLogger, Oai2ToOai3 } from "../src/converter";
import { OpenAPI2Document } from "../src/oai2";
const logger: ConverterLogger = {
trackError: jest.fn(),

Просмотреть файл

@ -1,6 +1,6 @@
import { serializeJsonPointer } from "@azure-tools/json";
import { OpenAPI2Document } from "@azure-tools/openapi/v2";
import { ConverterLogger, Oai2ToOai3 } from "../src";
import { OpenAPI2Document } from "../src/oai2";
const defaultOpenApi2 = {
swagger: "2.0",

Просмотреть файл

@ -4,6 +4,24 @@
"description": "OpenAPI common code for Azure Tools.",
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",
"exports": {
".": "./dist/index.js",
"./v2": "./dist/v2/index.js",
"./v3": "./dist/v3/index.js"
},
"typesVersions": {
"*": {
"*": [
"./dist/index.d.ts"
],
"v2": [
"./dist/v2/index.d.ts"
],
"v3": [
"./dist/v3/index.d.ts"
]
}
},
"engines": {
"node": ">=12.0.0"
},
@ -46,7 +64,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"rimraf": "^3.0.2",
"typescript": "~4.4.2"
},

Просмотреть файл

@ -1,3 +1,3 @@
# Project: @azure-tools/openapi
# @azure-tools/openapi
Contains types reprensting OpenAPI 3.0 documents
Library providing types for OpenAPI 2.0 and OpenAPI 3.0 as well as some utilities to manipulate those documents.

Просмотреть файл

@ -1,22 +1,17 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export interface PathReference {
$ref: string;
}
export type Refable<T> = T | PathReference;
export interface Dereferenced<T> {
instance: T;
name: string;
fromRef?: boolean;
}
export type Reference<T> = T;
export type Refable<T> = T | PathReference;
export type ExtensionKey = `x-${string}`;
export type EnumStr<T extends string> = `${T}`;
export type Extensions = {
[key in ExtensionKey]: any;
};

Просмотреть файл

@ -1,9 +1,3 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export * from "./oai3";
export * from "./formats";
export * from "./common";
export * from "./utils";
export * from "./v3";

Просмотреть файл

@ -1,25 +1,21 @@
import { PathReference } from "../common";
export interface OpenAPI2Definition {
[key: string]: unknown;
additionalProperties?: OpenAPI2Definition | OpenAPI2Reference | boolean;
additionalProperties?: OpenAPI2Definition | PathReference | boolean;
allOf?: OpenAPI2Definition[];
description?: string;
enum?: string[];
format?: string;
items?: OpenAPI2Definition | OpenAPI2Reference;
oneOf?: (OpenAPI2Definition | OpenAPI2Reference)[];
properties?: { [index: string]: OpenAPI2Definition | OpenAPI2Reference };
items?: OpenAPI2Definition | PathReference;
oneOf?: (OpenAPI2Definition | PathReference)[];
properties?: { [index: string]: OpenAPI2Definition | PathReference };
required?: string[];
title?: string;
type?: OpenAPI2Type; // allow this to be optional to cover cases when this is missing
}
export interface OpenAPI2Reference<T = any> {
$ref: string;
}
export type Refable<T> = OpenAPI2Reference<T> | T;
export type OpenAPI2Type =
| "array"
| "boolean"

Просмотреть файл

@ -1,8 +1,9 @@
import { OpenAPI2Definition, OpenAPI2Reference } from "./definition";
import { PathReference } from "../common";
import { OpenAPI2Definition } from "./definition";
export interface OpenAPI2HeaderDefinition {
type: "string" | "number" | "integer" | "boolean" | "array";
schema: OpenAPI2Reference & OpenAPI2Definition;
schema: PathReference & OpenAPI2Definition;
items: any;
collectionFormat: "csv" | "ssv" | "tsv" | "pipes" | "multi";
description?: string;

Просмотреть файл

@ -1,4 +1,5 @@
import { OpenAPI2Definition, OpenAPI2Reference, Refable } from "./definition";
import { PathReference, Refable } from "../common";
import { OpenAPI2Definition } from "./definition";
import { OpenAPI2HeaderDefinition } from "./header";
import { OpenAPI2Parameter } from "./parameter";
@ -33,4 +34,4 @@ export interface OpenAPI2OperationResponse {
headers?: { [headerName: string]: OpenAPI2ResponseHeader };
}
export type OpenAPI2ResponseHeader = OpenAPI2Reference & OpenAPI2HeaderDefinition;
export type OpenAPI2ResponseHeader = PathReference & OpenAPI2HeaderDefinition;

Просмотреть файл

@ -0,0 +1 @@
export type EnumStr<T extends string> = `${T}`;

Просмотреть файл

@ -0,0 +1,6 @@
import { OpenAPI3Document } from "./oai3";
/**
* @deprecated use OpenAPI3Document
*/
export type Model = OpenAPI3Document;

Просмотреть файл

@ -0,0 +1,4 @@
export * from "./oai3";
export * from "./formats";
export * from "./common";
export * from "./deprecated";

Просмотреть файл

@ -3,25 +3,25 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { EnumStr, Refable as Reference } from "./common";
import { Extensions, Refable } from "../common";
import { EnumStr } from "./common";
export type Dictionary<T> = { [key: string]: T };
// OAI3 variants for the basic model definitions.
/** Nearly all classes can support additional key-value pairs where the key starts with 'x-' */
export interface Extensions {
[key: string]: any;
}
/** Properties, Parameters, Operations and Schemas require additional support */
export interface Implementation<T> {}
export interface Details {}
/** Property References may have additional data that's not in the target reference */
/**
* Property References may have additional data that's not in the target reference
*/
export interface PropertyDetails extends Details, Extensions {
description?: string;
readOnly?: boolean;
nullable?: boolean;
}
/** Parameter References may have additional data that's not in the target reference */
@ -73,12 +73,12 @@ export function isQueryParameter(parameter: Parameter): parameter is InQuery & P
/**
* Properties have additional data when referencing them
*/
export type PropertyReference<T> = PropertyDetails & Reference<T>;
export type PropertyReference<T> = PropertyDetails & Refable<T>;
/**
* Parameter references could have additional data to override the shared parameter value.
*/
export type ParameterReference<T> = ParameterDetails & Reference<T>;
export type ParameterReference<T> = ParameterDetails & Refable<T>;
/**
* @description common ways of serializing simple parameters
@ -130,9 +130,9 @@ export type QueryEncodingStyle =
| EncodingStyle.DeepObject;
export type PathEncodingStyle = EncodingStyle.Matrix | EncodingStyle.Label | EncodingStyle.Simple;
export interface Model extends Extensions {
export interface OpenAPI3Document extends Extensions {
paths: Dictionary<PathItem>;
openApi: string;
openapi: string;
info: Info;
externalDocs?: ExternalDocumentation;
servers?: Array<Server>;
@ -142,15 +142,15 @@ export interface Model extends Extensions {
}
export interface Components extends Extensions {
schemas?: Dictionary<Reference<Schema>>;
responses?: Dictionary<Reference<Response>>;
parameters?: Dictionary<Reference<Parameter>>;
examples?: Dictionary<Reference<Example>>;
requestBodies?: Dictionary<Reference<RequestBody>>;
headers?: Dictionary<Reference<Header>>;
securitySchemes?: Dictionary<Reference<SecurityScheme>>;
links?: Dictionary<Reference<Link>>;
callbacks?: Dictionary<Reference<Callback>>;
schemas?: Dictionary<Schema>;
responses?: Dictionary<Response>;
parameters?: Dictionary<Parameter>;
examples?: Dictionary<Example>;
requestBodies?: Dictionary<RequestBody>;
headers?: Dictionary<Header>;
securitySchemes?: Dictionary<SecurityScheme>;
links?: Dictionary<Link>;
callbacks?: Dictionary<Callback>;
}
export interface APIKeySecurityScheme extends Extensions {
@ -188,7 +188,7 @@ export interface Discriminator extends Extensions {
}
export interface Encoding extends Extensions {
contentType?: string;
headers?: Dictionary<Reference<Header>>;
headers?: Dictionary<Refable<Header>>;
style?: QueryEncodingStyle;
explode?: boolean;
allowReserved?: boolean;
@ -248,7 +248,7 @@ export interface MediaType extends Extensions, Partial<HasExample>, Partial<HasE
/** A map between a property name and its encoding information. The key, being the property name, MUST exist in the schema as a property. The encoding object SHALL only apply to requestBody objects when the media type is multipart or application/x-www-form-urlencoded. */
encoding?: Dictionary<Encoding>;
/** The schema defining the type used for the request body. */
schema?: Reference<Schema>;
schema?: Refable<Schema>;
}
export interface NonBearerHTTPSecurityScheme extends Extensions {
@ -280,9 +280,9 @@ export interface HttpOperation extends Deprecatable, Extensions, Implementation<
externalDocs?: ExternalDocumentation;
operationId?: string;
parameters?: ParameterReference<Parameter>[];
requestBody?: Reference<RequestBody>;
responses: Dictionary<Reference<Response>>;
callbacks?: Dictionary<Reference<Callback>>;
requestBody?: Refable<RequestBody>;
responses: Dictionary<Refable<Response>>;
callbacks?: Dictionary<Refable<Callback>>;
security?: Array<SecurityRequirement>;
servers?: Array<Server>;
@ -293,7 +293,7 @@ export interface Deprecatable {
}
export interface HasSchema {
schema: Reference<Schema>;
schema: Refable<Schema>;
explode?: boolean;
}
export interface HasContent {
@ -303,7 +303,7 @@ export interface HasExample {
example: any;
}
export interface HasExamples {
examples: Dictionary<Reference<HasExample>>;
examples: Dictionary<Refable<HasExample>>;
}
export interface InCookie extends HasSchema, Partial<HasExample>, Partial<HasExamples> {
in: ParameterLocation.Cookie;
@ -368,9 +368,9 @@ export interface RequestBody extends Extensions {
export interface Response extends Extensions {
description: string;
headers?: Dictionary<Reference<Header>>;
headers?: Dictionary<Refable<Header>>;
content?: Dictionary<MediaType>;
links?: Dictionary<Reference<Link>>;
links?: Dictionary<Refable<Link>>;
}
export interface Schema extends Deprecatable, Extensions, Implementation<SchemaDetails> {
@ -418,13 +418,13 @@ export interface Schema extends Deprecatable, Extensions, Implementation<SchemaD
enum?: Array<any>;
/* properties with potential references */
not?: Reference<Schema>;
allOf?: Array<Reference<Schema>>;
oneOf?: Array<Reference<Schema>>;
anyOf?: Array<Reference<Schema>>;
items?: Reference<Schema>;
not?: Refable<Schema>;
allOf?: Array<Refable<Schema>>;
oneOf?: Array<Refable<Schema>>;
anyOf?: Array<Refable<Schema>>;
items?: Refable<Schema>;
properties?: Dictionary<PropertyReference<Schema>>;
additionalProperties?: boolean | Reference<Schema>;
additionalProperties?: boolean | Refable<Schema>;
}
export interface Server extends Extensions {

Просмотреть файл

@ -40,7 +40,7 @@
"eslint-plugin-unicorn": "~33.0.1",
"eslint-plugin-import": "~2.24.2",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"rimraf": "^3.0.2",
"typescript": "~4.4.2"
},

Просмотреть файл

@ -35,7 +35,7 @@
"@azure-tools/tasks": "~3.0.0",
"expect": "~26.6.2",
"jest-snapshot": "~26.6.2",
"jest": "^27.0.4"
"jest": "^28.0.0-alpha.7"
},
"devDependencies": {
"@types/jest": "^26.0.20",

Просмотреть файл

@ -44,7 +44,7 @@
"eslint-plugin-prettier": "~3.4.0",
"eslint-plugin-unicorn": "~33.0.1",
"eslint": "^7.17.0",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"prettier": "~2.3.1",
"rimraf": "^3.0.2",
"typescript": "~4.4.2"

Просмотреть файл

@ -55,7 +55,7 @@
"commonmark": "^0.27.0",
"deep-equal": "^2.0.5",
"express": "~4.17.1",
"jest": "^27.0.4",
"jest": "^28.0.0-alpha.7",
"js-yaml": "~4.0.0",
"morgan": "^1.10.0",
"mustache": "^4.1.0",