This commit is contained in:
Timothee Guerin 2021-02-04 11:02:44 -08:00 коммит произвёл GitHub
Родитель 9e7354c8f9
Коммит 7647c172d2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 172 добавлений и 132 удалений

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

@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@autorest/core",
"comment": "",
"type": "none"
}
],
"packageName": "@autorest/core",
"email": "tiguerin@microsoft.com"
}

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

@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@autorest/modelerfour",
"comment": "",
"type": "none"
}
],
"packageName": "@autorest/modelerfour",
"email": "tiguerin@microsoft.com"
}

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

@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@azure-tools/openapi",
"comment": "Change types from using `: Optional<T>` to `?: T`",
"type": "minor"
}
],
"packageName": "@azure-tools/openapi",
"email": "tiguerin@microsoft.com"
}

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

@ -3,7 +3,7 @@ import { JsonType, Model } from "@azure-tools/openapi";
import { create } from "domain";
import { OAI3Shaker } from "./tree-shaker";
const createTestModel = (model: any): Model => {
const createTestModel = (model: Partial<Model>): Model => {
return {
openApi: "3.0.0",
paths: {},
@ -11,10 +11,10 @@ const createTestModel = (model: any): Model => {
title: "Test spec",
version: "1.0.0",
},
servers: {},
security: {},
servers: [],
security: [],
components: {},
tags: {},
tags: [],
...model,
};
};

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

@ -160,7 +160,7 @@ export class ModelerFour {
contact: i.contact,
license: i.license,
termsOfService: i.termsOfService,
externalDocs: filterOutXDash<ExternalDocumentation>(this.input.externalDocs),
externalDocs: filterOutXDash<ExternalDocumentation>(this.input.externalDocs as any),
extensions: Interpretations.getExtensionProperties(i),
},
extensions: Interpretations.getExtensionProperties(this.input),

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

@ -1,10 +1,9 @@
{
"name": "@azure-tools/openapi",
"version": "3.0.0",
"patchOffset": 100,
"version": "3.0.261",
"description": "OpenAPI common code for Azure Tools.",
"main": "./dist/main.js",
"typings": "./dist/main.d.ts",
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",
"engines": {
"node": ">=10.12.0"
},
@ -48,7 +47,5 @@
"rimraf": "^3.0.2",
"typescript": "~4.1.3"
},
"dependencies": {
"@azure-tools/linq": "~3.1.0"
}
"dependencies": {}
}

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

@ -3,27 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Dictionary, ToDictionary, items } from "@azure-tools/linq";
export function includeXDash<T>(dictionary: Dictionary<T>) {
return Object.keys(dictionary).filter((v, i, a) => v.startsWith("x-"));
}
export function excludeXDash<T>(dictionary: Dictionary<T>) {
return Object.keys(dictionary).filter((v, i, a) => !v.startsWith("x-"));
}
export function filterOutXDash<T>(obj: any) {
if (obj) {
const result = <any>{};
for (const { key, value } of items(obj).where((each) => !each.key.startsWith("x-"))) {
result[key] = <any>value;
}
return result;
}
return undefined;
}
export interface PathReference<T> {
export interface PathReference {
$ref: string;
}
@ -35,49 +15,6 @@ export interface Dereferenced<T> {
export type Reference<T> = T;
export type Refable<T> = T | PathReference<T>;
export type Optional<T> = T | undefined;
export type Refable<T> = T | PathReference;
export function typeOf(obj: any) {
const t = typeof obj;
return t === "object" ? (Array.isArray(obj) ? "array" : "object") : t;
}
/** identifies if a given refable is a reference or an instance */
export function isReference<T>(item: Refable<T>): item is PathReference<T> {
return item && (<PathReference<T>>item).$ref ? true : false;
}
/** gets an object instance for the item, regardless if it's a reference or not. */
export function dereference<T>(document: any, item: Refable<T>, stack = new Array<string>()): Dereferenced<T> {
let name: string | undefined;
if (isReference(item)) {
let node = document;
const path = item.$ref;
if (stack.indexOf(path) > -1) {
throw new Error(`Circular $ref in Model -- ${path} :: ${JSON.stringify(stack)}`);
}
stack.push(path);
const parts = path.replace("#/", "").split("/");
for (name of parts) {
if (!node[name]) {
throw new Error(`Invalid Reference ${name} -- ${path}`);
}
node = node[name];
}
if (isReference(node)) {
// it's a ref to a ref.
return dereference(document, node, stack);
}
return { instance: node, name: name || "", fromRef: true };
}
return { instance: item, name: "", fromRef: false };
}
export function getExtensionProperties(dictionary: Dictionary<any>): Dictionary<any> {
return ToDictionary(includeXDash(dictionary), (each) => dictionary[each]);
}
export type ExtensionKey = `x-${string}`;

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

@ -4,5 +4,6 @@
*--------------------------------------------------------------------------------------------*/
export * from "./oai3";
export * from "./common";
export * from "./formats";
export * from "./common";
export * from "./utils";

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

@ -3,8 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Dictionary } from "@azure-tools/linq";
import { Optional, Refable as Reference } from "./common";
import { Refable as Reference } from "./common";
export type Dictionary<T> = { [key: string]: T };
// OAI3 variants for the basic model definitions.
@ -123,22 +124,22 @@ export interface Model extends Extensions {
openApi: string;
info: Info;
externalDocs?: ExternalDocumentation;
servers: Optional<Array<Server>>;
security: Optional<Array<SecurityRequirement>>;
tags: Optional<Array<Tag>>;
components: Optional<Components>;
servers?: Array<Server>;
security?: Array<SecurityRequirement>;
tags?: Array<Tag>;
components?: Components;
}
export interface Components extends Extensions {
schemas: Optional<Dictionary<Reference<Schema>>>;
responses: Optional<Dictionary<Reference<Response>>>;
parameters: Optional<Dictionary<Reference<Parameter>>>;
examples: Optional<Dictionary<Reference<Example>>>;
requestBodies: Optional<Dictionary<Reference<RequestBody>>>;
headers: Optional<Dictionary<Reference<Header>>>;
securitySchemes: Optional<Dictionary<Reference<SecurityScheme>>>;
links: Optional<Dictionary<Reference<Link>>>;
callbacks: Optional<Dictionary<Reference<Callback>>>;
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>>;
}
export interface APIKeySecurityScheme extends Extensions {
@ -151,7 +152,7 @@ export interface AuthorizationCodeOAuthFlow extends Extensions {
authorizationUrl: string; // uriref
tokenUrl: string; // uriref
refreshUrl?: string; // uriref
scopes: Optional<Dictionary<string>>;
scopes?: Dictionary<string>;
}
export interface BearerHTTPSecurityScheme extends Extensions {
scheme: Scheme.Bearer;
@ -162,7 +163,7 @@ export interface BearerHTTPSecurityScheme extends Extensions {
export interface ClientCredentialsFlow extends Extensions {
tokenUrl: string; // uriref
refreshUrl?: string; // uriref
scopes: Optional<Dictionary<string>>;
scopes?: Dictionary<string>;
}
export interface Contact extends Extensions {
@ -172,11 +173,11 @@ export interface Contact extends Extensions {
}
export interface Discriminator extends Extensions {
propertyName: string;
mapping: Optional<Dictionary<string>>;
mapping?: Dictionary<string>;
}
export interface Encoding extends Extensions {
contentType?: string;
headers: Optional<Dictionary<Reference<Header>>>;
headers?: Dictionary<Reference<Header>>;
style?: QueryEncodingStyle;
explode?: boolean;
allowReserved?: boolean;
@ -199,10 +200,10 @@ export interface Header
Partial<HasExample>,
Partial<HasExamples> {
description?: string;
required: Optional<boolean>;
deprecated: Optional<boolean>;
allowEmptyValue: Optional<boolean>;
allowReserved: Optional<boolean>;
required?: boolean;
deprecated?: boolean;
allowEmptyValue?: boolean;
allowReserved?: boolean;
}
export interface ImplicitOAuthFlow extends Extensions {
@ -226,7 +227,7 @@ export interface License extends Extensions {
export interface Link extends Extensions {
operationRef?: string; // uriref
operationId?: string;
parameters: Optional<Dictionary<string>>;
parameters?: Dictionary<string>;
requestBody?: any;
description?: string;
server?: Server;
@ -234,7 +235,7 @@ export interface Link extends Extensions {
export interface MediaType extends Extensions, Partial<HasExample>, Partial<HasExamples> {
/** 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: Optional<Dictionary<Encoding>>;
encoding?: Dictionary<Encoding>;
/** The schema defining the type used for the request body. */
schema?: Reference<Schema>;
}
@ -261,18 +262,18 @@ export interface OpenIdConnectSecurityScheme extends Extensions {
description?: string;
}
export interface HttpOperation extends Extensions, Implementation<HttpOperationDetails> {
tags: Optional<Array<string>>;
tags?: Array<string>;
summary?: string;
description?: string;
externalDocs?: ExternalDocumentation;
operationId?: string;
parameters: Optional<Array<Reference<Parameter>>>;
parameters?: Array<Reference<Parameter>>;
requestBody?: Reference<RequestBody>;
responses: Dictionary<Reference<Response>>;
callbacks: Optional<Dictionary<Reference<Callback>>>;
callbacks?: Dictionary<Reference<Callback>>;
deprecated?: boolean;
security: Optional<Array<SecurityRequirement>>;
servers: Optional<Array<Server>>;
security?: Array<SecurityRequirement>;
servers?: Array<Server>;
}
export interface HasSchema {
@ -316,9 +317,9 @@ export interface Parameter
in: ParameterLocation;
description?: string;
allowEmptyValue: Optional<boolean>;
deprecated: Optional<boolean>;
required: Optional<boolean>;
allowEmptyValue?: boolean;
deprecated?: boolean;
required?: boolean;
style?: EncodingStyle;
allowReserved?: boolean;
@ -327,7 +328,7 @@ export interface Parameter
export interface PasswordOAuthFlow extends Extensions {
tokenUrl: string; // uriref
refreshUrl?: string; // uriref
scopes: Optional<Dictionary<string>>;
scopes?: Dictionary<string>;
}
export interface PathItem extends Extensions {
$ref?: string | PathItem;
@ -341,20 +342,20 @@ export interface PathItem extends Extensions {
head?: HttpOperation;
patch?: HttpOperation;
trace?: HttpOperation;
servers: Optional<Array<Server>>;
parameters: Optional<Array<Reference<Parameter>>>;
servers?: Array<Server>;
parameters?: Array<Reference<Parameter>>;
}
export interface RequestBody extends Extensions {
description?: string;
content: Dictionary<MediaType>;
required: Optional<boolean>;
required?: boolean;
}
export interface Response extends Extensions {
description: string;
headers: Optional<Dictionary<Reference<Header>>>;
content: Optional<Dictionary<MediaType>>;
links: Optional<Dictionary<Reference<Link>>>;
headers?: Dictionary<Reference<Header>>;
content?: Dictionary<MediaType>;
links?: Dictionary<Reference<Link>>;
}
export interface Schema extends Extensions, Implementation<SchemaDetails> {
@ -363,11 +364,11 @@ export interface Schema extends Extensions, Implementation<SchemaDetails> {
title?: string;
description?: string;
format?: string;
nullable: Optional<boolean>;
readOnly: Optional<boolean>;
writeOnly: Optional<boolean>;
deprecated: Optional<boolean>;
required: Optional<Array<string>>;
nullable?: boolean;
readOnly?: boolean;
writeOnly?: boolean;
deprecated?: boolean;
required?: Array<string>;
/* number restrictions */
multipleOf?: number;
@ -400,25 +401,25 @@ export interface Schema extends Extensions, Implementation<SchemaDetails> {
xml?: XML;
/* Properties that are collections of things that are not references */
enum: Optional<Array<any>>;
enum?: Array<any>;
/* properties with potential references */
not?: Reference<Schema>;
allOf: Optional<Array<Reference<Schema>>>;
oneOf: Optional<Array<Reference<Schema>>>;
anyOf: Optional<Array<Reference<Schema>>>;
allOf?: Array<Reference<Schema>>;
oneOf?: Array<Reference<Schema>>;
anyOf?: Array<Reference<Schema>>;
items?: Reference<Schema>;
properties: Optional<Dictionary<PropertyReference<Schema>>>;
properties?: Dictionary<PropertyReference<Schema>>;
additionalProperties?: boolean | Reference<Schema>;
}
export interface Server extends Extensions {
url: string;
description?: string;
variables: Optional<Dictionary<ServerVariable>>;
variables?: Dictionary<ServerVariable>;
}
export interface ServerVariable extends Extensions {
enum: Optional<Array<string>>;
enum?: Array<string>;
default: string;
description?: string;
}

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

@ -0,0 +1,71 @@
import { Dereferenced, ExtensionKey, PathReference, Refable } from "./common";
/**
* Only return properties starting with x-
* @param dictionary
*/
export const includeXDash = (dictionary: Record<string, unknown>): ExtensionKey[] => {
return Object.keys(dictionary).filter((v, i, a) => v.startsWith("x-")) as any;
};
/**
* Only return properties NOT starting with x-
* @param dictionary
*/
export const excludeXDash = <T extends Record<string, unknown>>(dictionary: T): string[] => {
return Object.keys(dictionary).filter((v, i, a) => !v.startsWith("x-"));
};
export const filterOutXDash = <T>(obj: T | undefined): T | undefined => {
if (obj) {
const result = <any>{};
for (const [key, value] of Object.entries(obj).filter(([key, value]) => !key.startsWith("x-"))) {
result[key] = <any>value;
}
return result;
}
return undefined;
};
/**
* Identifies if a given refable is a reference or an instance
* @param item Check if item is a reference.
*/
export const isReference = <T>(item: Refable<T>): item is PathReference => {
return item && (<PathReference>item).$ref ? true : false;
};
/**
* Gets an object instance for the item, regardless if it's a reference or not.
* @param document Entire document.
* @param item Reference item.
* @param stack Stack for circular dependencies.
*/
export const dereference = <T>(document: any, item: Refable<T>, stack: string[] = []): Dereferenced<T> => {
let name: string | undefined;
if (isReference(item)) {
let node = document;
const path = item.$ref;
if (stack.indexOf(path) > -1) {
throw new Error(`Circular $ref in Model -- ${path} :: ${JSON.stringify(stack)}`);
}
stack.push(path);
const parts = path.replace("#/", "").split("/");
for (name of parts) {
if (!node[name]) {
throw new Error(`Invalid Reference ${name} -- ${path}`);
}
node = node[name];
}
if (isReference(node)) {
// it's a ref to a ref.
return dereference<T>(document, node, stack);
}
return { instance: node, name: name || "", fromRef: true };
}
return { instance: item, name: "", fromRef: false };
};

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

@ -11,7 +11,7 @@
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
"declaration": true /* Generates corresponding '.d.ts' file. */,
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
"declarationMap": true /* Generates a sourcemap for each corresponding '.d.ts' file. */,
"sourceMap": true /* Generates corresponding '.map' file. */,
// "outFile": "./", /* Concatenate and emit output to single file. */
// "outDir": "./dist" /* Redirect output structure to the directory. */,