[angular] Add option to generate tagged unions (#7245)

Using the option `taggedUnions` will create a union type for each parent
type instead of extending interfaces. The union types are tagged by using
the discriminator values.

And also:
* Add support for aliases;
* Add support for read-only properties.
This commit is contained in:
Erik Timmers 2018-02-01 10:20:50 +01:00 committed by William Cheng
parent 36f69a034d
commit 157e6b7fab
46 changed files with 462 additions and 79 deletions

View File

@ -27,6 +27,7 @@ import io.swagger.models.properties.Property;
import io.swagger.models.properties.StringProperty;
public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig {
private static final String X_DISCRIMINATOR_TYPE = "x-discriminator-value";
private static final String UNDEFINED_VALUE = "undefined";
protected String modelPropertyNaming= "camelCase";
@ -330,7 +331,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
if (p instanceof StringProperty) {
StringProperty sp = (StringProperty) p;
if (sp.getDefault() != null) {
return "\"" + sp.getDefault() + "\"";
return "'" + sp.getDefault() + "'";
}
return UNDEFINED_VALUE;
} else if (p instanceof BooleanProperty) {
@ -495,17 +496,44 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
cm.imports = new TreeSet(cm.imports);
// name enum with model name, e.g. StatusEnum => Pet.StatusEnum
for (CodegenProperty var : cm.vars) {
// name enum with model name, e.g. StatuEnum => Pet.StatusEnum
if (Boolean.TRUE.equals(var.isEnum)) {
var.datatypeWithEnum = var.datatypeWithEnum.replace(var.enumName, cm.classname + "." + var.enumName);
}
}
if (cm.parent != null) {
for (CodegenProperty var : cm.allVars) {
if (Boolean.TRUE.equals(var.isEnum)) {
var.datatypeWithEnum = var.datatypeWithEnum
.replace(var.enumName, cm.classname + "." + var.enumName);
}
}
}
}
return objs;
}
@Override
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
Map<String, Object> result = super.postProcessAllModels(objs);
for (Map.Entry<String, Object> entry : result.entrySet()) {
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
if (cm.discriminator != null && cm.children != null) {
for (CodegenModel child : cm.children) {
this.setDiscriminatorValue(child, cm.discriminator, this.getDiscriminatorValue(child));
}
}
}
}
return result;
}
public void setSupportsES6(Boolean value) {
supportsES6 = value;
}
@ -514,6 +542,25 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
return supportsES6;
}
private void setDiscriminatorValue(CodegenModel model, String baseName, String value) {
for (CodegenProperty prop : model.allVars) {
if (prop.baseName.equals(baseName)) {
prop.discriminatorValue = value;
}
}
if (model.children != null) {
final boolean newDiscriminator = model.discriminator != null;
for (CodegenModel child : model.children) {
this.setDiscriminatorValue(child, baseName, newDiscriminator ? value : this.getDiscriminatorValue(child));
}
}
}
private String getDiscriminatorValue(CodegenModel model) {
return model.vendorExtensions.containsKey(X_DISCRIMINATOR_TYPE) ?
(String) model.vendorExtensions.get(X_DISCRIMINATOR_TYPE) : model.classname;
}
@Override
public String escapeQuotationMark(String input) {
// remove ', " to avoid code injection

View File

@ -21,18 +21,22 @@ import io.swagger.models.properties.*;
public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCodegen {
private static final SimpleDateFormat SNAPSHOT_SUFFIX_FORMAT = new SimpleDateFormat("yyyyMMddHHmm");
private static final String X_DISCRIMINATOR_TYPE = "x-discriminator-value";
public static final String NPM_NAME = "npmName";
public static final String NPM_VERSION = "npmVersion";
public static final String NPM_REPOSITORY = "npmRepository";
public static final String SNAPSHOT = "snapshot";
public static final String WITH_INTERFACES = "withInterfaces";
public static final String TAGGED_UNIONS ="taggedUnions";
public static final String NG_VERSION = "ngVersion";
protected String npmName = null;
protected String npmVersion = "1.0.0";
protected String npmRepository = null;
private boolean taggedUnions = false;
public TypeScriptAngularClientCodegen() {
super();
this.outputFolder = "generated-code/typescript-angular";
@ -55,6 +59,9 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
this.cliOptions.add(new CliOption(WITH_INTERFACES,
"Setting this property to true will generate interfaces next to the default class implementations.",
BooleanProperty.TYPE).defaultValue(Boolean.FALSE.toString()));
this.cliOptions.add(new CliOption(TAGGED_UNIONS,
"Use discriminators to create tagged unions instead of extending interfaces.",
BooleanProperty.TYPE).defaultValue(Boolean.FALSE.toString()));
this.cliOptions.add(new CliOption(NG_VERSION, "The version of Angular. Default is '4.3'"));
}
@ -101,6 +108,10 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
}
}
if (additionalProperties.containsKey(TAGGED_UNIONS)) {
taggedUnions = Boolean.parseBoolean(additionalProperties.get(TAGGED_UNIONS).toString());
}
// determine NG version
SemVer ngVersion;
if (additionalProperties.containsKey(NG_VERSION)) {
@ -295,14 +306,33 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
Map<String, Object> result = super.postProcessModels(objs);
// Add additional filename information for imports
List<Object> models = (List<Object>) postProcessModelsEnum(result).get("models");
for (Object _mo : models) {
Map<String, Object> mo = (Map<String, Object>) _mo;
CodegenModel cm = (CodegenModel) mo.get("model");
mo.put("tsImports", toTsImports(cm, cm.imports));
return postProcessModelsEnum(result);
}
@Override
public Map<String, Object> postProcessAllModels(Map<String, Object> objs) {
Map<String, Object> result = super.postProcessAllModels(objs);
for (Map.Entry<String, Object> entry : result.entrySet()) {
Map<String, Object> inner = (Map<String, Object>) entry.getValue();
List<Map<String, Object>> models = (List<Map<String, Object>>) inner.get("models");
for (Map<String, Object> mo : models) {
CodegenModel cm = (CodegenModel) mo.get("model");
if (taggedUnions) {
mo.put(TAGGED_UNIONS, true);
if (cm.discriminator != null && cm.children != null) {
for (CodegenModel child : cm.children) {
cm.imports.add(child.classname);
}
}
if (cm.parent != null) {
cm.imports.remove(cm.parent);
}
}
// Add additional filename information for imports
mo.put("tsImports", toTsImports(cm, cm.imports));
}
}
return result;
}

View File

@ -11,6 +11,6 @@ import { {{classname}} } from './{{filename}}';
* {{{description}}}
*/
{{/description}}
{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{>modelGeneric}}{{/isEnum}}
{{#isEnum}}{{>modelEnum}}{{/isEnum}}{{^isEnum}}{{#isAlias}}{{>modelAlias}}{{/isAlias}}{{^isAlias}}{{#taggedUnions}}{{>modelTaggedUnion}}{{/taggedUnions}}{{^taggedUnions}}{{>modelGeneric}}{{/taggedUnions}}{{/isAlias}}{{/isEnum}}
{{/model}}
{{/models}}

View File

@ -0,0 +1 @@
export type {{classname}} = {{dataType}};

View File

@ -1,28 +1,10 @@
export interface {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
{{#additionalPropertiesType}}
[key: string]: {{{additionalPropertiesType}}}{{#hasVars}} | any{{/hasVars}};
{{/additionalPropertiesType}}
export interface {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{ {{>modelGenericAdditionalProperties}}
{{#vars}}
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
{{name}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};
{{#isReadOnly}}readonly {{/isReadOnly}}{{name}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};
{{/vars}}
}{{#hasEnums}}
export namespace {{classname}} {
{{#vars}}
{{#isEnum}}
export type {{enumName}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}};
export const {{enumName}} = {
{{#allowableValues}}
{{#enumVars}}
{{name}}: {{{value}}} as {{enumName}}{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
}
{{/isEnum}}
{{/vars}}
}{{/hasEnums}}
}{{>modelGenericEnums}}

View File

@ -0,0 +1,5 @@
{{#additionalPropertiesType}}
[key: string]: {{{additionalPropertiesType}}}{{#hasVars}} | any{{/hasVars}};
{{/additionalPropertiesType}}

View File

@ -0,0 +1,16 @@
{{#hasEnums}}
export namespace {{classname}} {
{{#vars}}
{{#isEnum}}
export type {{enumName}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}};
export const {{enumName}} = {
{{#allowableValues}}
{{#enumVars}}
{{name}}: {{{value}}} as {{enumName}}{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
}
{{/isEnum}}
{{/vars}}
}{{/hasEnums}}

View File

@ -0,0 +1,21 @@
{{#discriminator}}
export type {{classname}} = {{#children}}{{^-first}} | {{/-first}}{{classname}}{{/children}};
{{/discriminator}}
{{^discriminator}}
{{#parent}}
export interface {{classname}} { {{>modelGenericAdditionalProperties}}
{{#allVars}}
{{#description}}
/**
* {{{description}}}
*/
{{/description}}
{{name}}{{^required}}?{{/required}}: {{#discriminatorValue}}'{{discriminatorValue}}'{{/discriminatorValue}}{{^discriminatorValue}}{{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}}{{/discriminatorValue}};
{{/allVars}}
}
{{>modelGenericEnums}}
{{/parent}}
{{^parent}}
{{>modelGeneric}}
{{/parent}}
{{/discriminator}}

View File

@ -35,6 +35,7 @@ public class TypeScriptAngularClientOptionsProvider implements OptionsProvider {
.put(TypeScriptAngularClientCodegen.NPM_VERSION, NMP_VERSION)
.put(TypeScriptAngularClientCodegen.SNAPSHOT, Boolean.FALSE.toString())
.put(TypeScriptAngularClientCodegen.WITH_INTERFACES, Boolean.FALSE.toString())
.put(TypeScriptAngularClientCodegen.TAGGED_UNIONS, Boolean.FALSE.toString())
.put(TypeScriptAngularClientCodegen.NPM_REPOSITORY, NPM_REPOSITORY)
.put(TypeScriptAngularClientCodegen.NG_VERSION, NG_VERSION)
.put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE)

View File

@ -4,7 +4,6 @@ import io.swagger.codegen.AbstractOptionsTest;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.languages.TypeScriptAngularClientCodegen;
import io.swagger.codegen.options.TypeScriptAngularClientOptionsProvider;
import io.swagger.codegen.options.TypeScriptAngularClientOptionsProvider;
import mockit.Expectations;
import mockit.Tested;

View File

@ -1,21 +1,28 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpModule } from '@angular/http';
import { HttpClientModule } from '@angular/common/http';
import { Configuration } from './configuration';
import { FakeService } from './api/fake.service';
@NgModule({
imports: [ CommonModule, HttpModule ],
imports: [ CommonModule, HttpClientModule ],
declarations: [],
exports: [],
providers: [ FakeService ]
providers: [
FakeService ]
})
export class ApiModule {
public static forConfig(configurationFactory: () => Configuration): ModuleWithProviders {
public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders {
return {
ngModule: ApiModule,
providers: [ { provide: Configuration, useFactory: configurationFactory } ]
}
}
constructor( @Optional() @SkipSelf() parentModule: ApiModule) {
if (parentModule) {
throw new Error('ApiModule is already loaded. Import your base AppModule only.');
}
}
}

View File

@ -9,19 +9,18 @@
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/* tslint:disable:no-unused-variable member-ordering */
import { Inject, Injectable, Optional } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { HttpClient, HttpHeaders, HttpParams,
HttpResponse, HttpEvent } from '@angular/common/http';
import { CustomHttpUrlEncodingCodec } from '../encoder';
import { Observable } from 'rxjs/Observable';
import '../rxjs-operators';
import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
import { Configuration } from '../configuration';
import { CustomHttpUrlEncodingCodec } from '../encoder';
@Injectable()
@ -56,21 +55,36 @@ export class FakeService {
}
/**
* To test code injection *_/ &#39; \&quot; &#x3D;end -- \\r\\n \\n \\r
*
* @param test code inject * &#39; &quot; &#x3D;end rn n r To test code injection *_/ &#39; \&quot; &#x3D;end -- \\r\\n \\n \\r
* @param testCodeInjectEndRnNR To test code injection *_/ &#39; \&quot; &#x3D;end -- \\r\\n \\n \\r
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
public testCodeInjectEndRnNR(test code inject * &#39; &quot; &#x3D;end rn n r?: string): Observable<{}> {
public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe?: 'body', reportProgress?: boolean): Observable<any>;
public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
public testCodeInjectEndRnNR(testCodeInjectEndRnNR?: string, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
let headers = this.defaultHeaders;
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'application/json',
'*_/ =end -- '
];
let httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers = headers.set("Accept", httpHeaderAcceptSelected);
}
// to determine the Content-Type header
let consumes: string[] = [
'application/json',
'*_/ =end -- '
];
const canConsumeForm = this.canConsumeForm(consumes);
let formParams: { append(param: string, value: any): void; };
@ -82,17 +96,19 @@ export class FakeService {
formParams = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()});
}
if (test code inject * &#39; &quot; &#x3D;end rn n r !== undefined) {
formParams = formParams.append('test code inject */ &#39; &quot; &#x3D;end -- \r\n \n \r', <any>test code inject * &#39; &quot; &#x3D;end rn n r) || formParams;
if (testCodeInjectEndRnNR !== undefined) {
formParams = formParams.append('test code inject */ &#39; &quot; &#x3D;end -- \r\n \n \r', <any>testCodeInjectEndRnNR) || formParams;
}
return this.httpClient.put<any>(`${this.basePath}/fake`,
convertFormParamsToString ? formParams.toString() : formParams, {
headers: headers,
convertFormParamsToString ? formParams.toString() : formParams,
{
withCredentials: this.configuration.withCredentials,
});
headers: headers,
observe: observe,
reportProgress: reportProgress
}
);
}
}

View File

@ -23,4 +23,57 @@ export class Configuration {
this.basePath = configurationParameters.basePath;
this.withCredentials = configurationParameters.withCredentials;
}
/**
* Select the correct content-type to use for a request.
* Uses {@link Configuration#isJsonMime} to determine the correct content-type.
* If no content type is found return the first found type if the contentTypes is not empty
* @param {string[]} contentTypes - the array of content types that are available for selection
* @returns {string} the selected content-type or <code>undefined</code> if no selection could be made.
*/
public selectHeaderContentType (contentTypes: string[]): string | undefined {
if (contentTypes.length == 0) {
return undefined;
}
let type = contentTypes.find(x => this.isJsonMime(x));
if (type === undefined) {
return contentTypes[0];
}
return type;
}
/**
* Select the correct accept content-type to use for a request.
* Uses {@link Configuration#isJsonMime} to determine the correct accept content-type.
* If no content type is found return the first found type if the contentTypes is not empty
* @param {string[]} accepts - the array of content types that are available for selection.
* @returns {string} the selected content-type or <code>undefined</code> if no selection could be made.
*/
public selectHeaderAccept(accepts: string[]): string | undefined {
if (accepts.length == 0) {
return undefined;
}
let type = accepts.find(x => this.isJsonMime(x));
if (type === undefined) {
return accepts[0];
}
return type;
}
/**
* Check if the given MIME is a JSON MIME.
* JSON MIME examples:
* application/json
* application/json; charset=UTF8
* APPLICATION/JSON
* application/vnd.company+json
* @param {string} mime - MIME (Multipurpose Internet Mail Extensions)
* @return {boolean} True if the given MIME is JSON, false otherwise.
*/
public isJsonMime(mime: string): boolean {
const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i');
return mime != null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json');
}
}

View File

@ -36,7 +36,7 @@ git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment."
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git

View File

@ -0,0 +1,22 @@
/**
* Swagger Petstore *_/ ' \" =end -- \\r\\n \\n \\r
* This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end --
*
* OpenAPI spec version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r
* Contact: apiteam@swagger.io *_/ ' \" =end -- \\r\\n \\n \\r
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r
*/
export interface ModelReturn {
/**
* property description *_/ ' \" =end -- \\r\\n \\n \\r
*/
_return?: number;
}

View File

@ -0,0 +1,21 @@
/**
* Swagger Petstore
* This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
*
* OpenAPI spec version: 1.0.0
* Contact: apiteam@swagger.io
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* Describes the result of uploading an image resource
*/
export interface ApiResponse {
code?: number;
type?: string;
message?: string;
}

View File

@ -0,0 +1,21 @@
/**
* Swagger Petstore
* This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
*
* OpenAPI spec version: 1.0.0
* Contact: apiteam@swagger.io
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* Describes the result of uploading an image resource
*/
export interface ApiResponse {
code?: number;
type?: string;
message?: string;
}

View File

@ -0,0 +1,20 @@
/**
* Swagger Petstore
* This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
*
* OpenAPI spec version: 1.0.0
* Contact: apiteam@swagger.io
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* A category for a pet
*/
export interface Category {
id?: number;
name?: string;
}

View File

@ -0,0 +1,35 @@
/**
* Swagger Petstore
* This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
*
* OpenAPI spec version: 1.0.0
* Contact: apiteam@swagger.io
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* An order for a pets from the pet store
*/
export interface Order {
id?: number;
petId?: number;
quantity?: number;
shipDate?: Date;
/**
* Order Status
*/
status?: Order.StatusEnum;
complete?: boolean;
}
export namespace Order {
export type StatusEnum = 'placed' | 'approved' | 'delivered';
export const StatusEnum = {
Placed: 'placed' as StatusEnum,
Approved: 'approved' as StatusEnum,
Delivered: 'delivered' as StatusEnum
}
}

View File

@ -0,0 +1,37 @@
/**
* Swagger Petstore
* This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
*
* OpenAPI spec version: 1.0.0
* Contact: apiteam@swagger.io
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { Category } from './category';
import { Tag } from './tag';
/**
* A pet for sale in the pet store
*/
export interface Pet {
id?: number;
category?: Category;
name: string;
photoUrls: Array<string>;
tags?: Array<Tag>;
/**
* pet status in the store
*/
status?: Pet.StatusEnum;
}
export namespace Pet {
export type StatusEnum = 'available' | 'pending' | 'sold';
export const StatusEnum = {
Available: 'available' as StatusEnum,
Pending: 'pending' as StatusEnum,
Sold: 'sold' as StatusEnum
}
}

View File

@ -0,0 +1,20 @@
/**
* Swagger Petstore
* This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
*
* OpenAPI spec version: 1.0.0
* Contact: apiteam@swagger.io
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* A tag for a pet
*/
export interface Tag {
id?: number;
name?: string;
}

View File

@ -0,0 +1,29 @@
/**
* Swagger Petstore
* This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
*
* OpenAPI spec version: 1.0.0
* Contact: apiteam@swagger.io
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* A User who is purchasing from the pet store
*/
export interface User {
id?: number;
username?: string;
firstName?: string;
lastName?: string;
email?: string;
password?: string;
phone?: string;
/**
* User Status
*/
userStatus?: number;
}