This commit is contained in:
Johannes Bader 2017-12-05 13:53:03 -08:00
Родитель 735d5b9a46
Коммит 679c9debd0
11 изменённых файлов: 578 добавлений и 302 удалений

291
.gitignore поставляемый
Просмотреть файл

@ -1,288 +1,3 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Typescript v1 declaration files
typings/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
node_modules/
.vscode/
package-lock.json

269
code-model-v1.d.ts поставляемый Normal file
Просмотреть файл

@ -0,0 +1,269 @@
declare type CollectionFormat =
'none' |
'csv' |
'ssv' |
'tsv' |
'pipes' |
'multi';
declare type Constraint =
'None' |
'InclusiveMaximum' |
'ExclusiveMaximum' |
'InclusiveMinimum' |
'ExclusiveMinimum' |
'MaxLength' |
'MinLength' |
'Pattern' |
'MaxItems' |
'MinItems' |
'UniqueItems' |
'MultipleOf';
declare type HttpMethod =
'get' |
'post' |
'put' |
'patch' |
'delete' |
'head' |
'options';
declare type HttpStatusCode =
'Continue' |
'SwitchingProtocols' |
'OK' |
'Created' |
'Accepted' |
'NonAuthoritativeInformation' |
'NoContent' |
'ResetContent' |
'PartialContent' |
'Ambiguous' |
'MultipleChoices' |
'Moved' |
'MovedPermanently' |
'Found' |
'Redirect' |
'RedirectMethod' |
'SeeOther' |
'NotModified' |
'UseProxy' |
'Unused' |
'RedirectKeepVerb' |
'TemporaryRedirect' |
'BadRequest' |
'Unauthorized' |
'PaymentRequired' |
'Forbidden' |
'NotFound' |
'MethodNotAllowed' |
'NotAcceptable' |
'ProxyAuthenticationRequired' |
'RequestTimeout' |
'Conflict' |
'Gone' |
'LengthRequired' |
'PreconditionFailed' |
'RequestEntityTooLarge' |
'RequestUriTooLong' |
'UnsupportedMediaType' |
'RequestedRangeNotSatisfiable' |
'ExpectationFailed' |
'UpgradeRequired' |
'InternalServerError' |
'NotImplemented' |
'BadGateway' |
'ServiceUnavailable' |
'GatewayTimeout' |
'HttpVersionNotSupported';
declare type KnownPrimaryType =
'none' |
'object' |
'int' |
'long' |
'double' |
'decimal' |
'string' |
'stream' |
'byteArray' |
'date' |
'dateTime' |
'dateTimeRfc1123' |
'timeSpan' |
'boolean' |
'credentials' |
'uuid' |
'base64Url' |
'unixTime';
declare type ParameterLocation =
'none' |
'path' |
'query' |
'header' |
'body' |
'formData';
declare interface WithExtensions {
extensions: { [key: string]: any };
}
declare interface CodeModel extends WithExtensions {
hostParametersFront?: Parameter[];
hostParametersBack?: Parameter[];
name: string;
namespace: string;
modelsName: string;
apiVersion: string;
baseUrl: string;
documentation?: string;
properties?: Property[];
operations?: MethodGroup[];
enumTypes?: EnumType[];
modelTypes?: CompositeType[];
errorTypes?: CompositeType[];
headerTypes?: CompositeType[];
}
declare interface FixableString {
raw?: string;
fixed: boolean;
}
declare interface XmlProperties {
name?: string;
namespace?: string;
prefix?: string;
attribute: boolean;
wrapped: boolean;
}
declare interface MethodGroup {
name: FixableString;
typeName: FixableString;
nameForProperty: string;
methods?: Method[];
}
declare interface Method extends WithExtensions {
name: FixableString;
group: FixableString;
serializedName: string;
url: string;
isAbsoluteUrl: boolean;
httpMethod: HttpMethod;
inputParameterTransformation?: ParameterTransformation[];
responses: {[statusCode in HttpStatusCode]: Response };
defaultResponse: Response;
returnType: Response;
description?: string;
summary?: string;
externalDocsUrl?: string;
requestContentType?: string;
responseContentTypes?: string[];
deprecated: boolean;
hidden: boolean;
parameters?: Parameter[];
}
declare interface ParameterTransformation {
outputParameter: Parameter;
parameterMappings?: ParameterMapping[];
}
declare interface ParameterMapping {
inputParameter: Parameter;
inputParameterProperty?: string;
outputParameterProperty?: string;
}
declare interface IVariable extends WithExtensions {
collectionFormat: CollectionFormat;
constraints?: {[constraint in Constraint]: string };
defaultValue: FixableString;
documentation?: string;
isRequired: boolean;
isConstant: boolean;
name: FixableString;
serializedName: FixableString;
modelType: ModelType;
}
declare interface Property extends IVariable {
isReadOnly: boolean;
summary?: string;
realPath: string[];
xmlProperties?: XmlProperties;
}
declare interface Parameter extends IVariable {
clientProperty?: Property;
location: ParameterLocation;
}
//
// Types
//
declare interface IModelType {
name: FixableString;
xmlProperties?: XmlProperties;
}
declare interface EnumType extends IModelType {
$type: "EnumType";
values: EnumValue;
modelAsExtensible: boolean;
modelAsString: boolean;
underlyingType: PrimaryType;
}
declare interface EnumValue {
description?: string;
name: string;
serializedName: string;
allowedValues?: string[];
}
declare interface PrimaryType extends IModelType {
$type: "PrimaryType";
format?: string;
knownPrimaryType: KnownPrimaryType;
}
declare interface CompositeType extends IModelType {
$type: "CompositeType";
serializedName: string;
baseModelType?: CompositeType;
polymorphicDiscriminator?: string;
summary?: string;
documentation?: string;
externalDocsUrl?: string;
containsConstantProperties: boolean;
properties?: Property[];
}
declare interface DictionaryType extends IModelType {
$type: "DictionaryType";
valueType: ModelType;
supportsAdditionalProperties: boolean;
}
declare interface SequenceType extends IModelType {
$type: "SequenceType";
elementType: ModelType;
elementXmlProperties?: XmlProperties;
}
type ModelType =
CompositeType |
DictionaryType |
EnumType |
PrimaryType |
SequenceType;

4
dist/index.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var extension_base_1 = require("./lib/extension-base");
exports.AutoRestExtension = extension_base_1.AutoRestExtension;

87
dist/lib/extension-base.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,87 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
var IAutoRestPluginTarget_Types;
(function (IAutoRestPluginTarget_Types) {
IAutoRestPluginTarget_Types.GetPluginNames = new vscode_jsonrpc_1.RequestType0("GetPluginNames");
IAutoRestPluginTarget_Types.Process = new vscode_jsonrpc_1.RequestType2("Process");
})(IAutoRestPluginTarget_Types || (IAutoRestPluginTarget_Types = {}));
var IAutoRestPluginInitiator_Types;
(function (IAutoRestPluginInitiator_Types) {
IAutoRestPluginInitiator_Types.ReadFile = new vscode_jsonrpc_1.RequestType2("ReadFile");
IAutoRestPluginInitiator_Types.GetValue = new vscode_jsonrpc_1.RequestType2("GetValue");
IAutoRestPluginInitiator_Types.ListInputs = new vscode_jsonrpc_1.RequestType1("ListInputs");
IAutoRestPluginInitiator_Types.WriteFile = new vscode_jsonrpc_1.NotificationType4("WriteFile");
IAutoRestPluginInitiator_Types.Message = new vscode_jsonrpc_1.NotificationType2("Message");
})(IAutoRestPluginInitiator_Types || (IAutoRestPluginInitiator_Types = {}));
class AutoRestExtension {
constructor() {
this.plugins = {};
}
Add(name, handler) {
this.plugins[name] = handler;
}
Run(input = process.stdin, output = process.stdout) {
return __awaiter(this, void 0, void 0, function* () {
// connection setup
const channel = vscode_jsonrpc_1.createMessageConnection(input, output, {
error(message) { console.error("error: ", message); },
info(message) { console.error("info: ", message); },
log(message) { console.error("log: ", message); },
warn(message) { console.error("warn: ", message); }
});
channel.onRequest(IAutoRestPluginTarget_Types.GetPluginNames, () => __awaiter(this, void 0, void 0, function* () { return Object.keys(this.plugins); }));
channel.onRequest(IAutoRestPluginTarget_Types.Process, (pluginName, sessionId) => __awaiter(this, void 0, void 0, function* () {
try {
const handler = this.plugins[pluginName];
if (!handler) {
throw new Error(`Plugin host could not find requested plugin '${pluginName}'.`);
}
yield handler({
ReadFile(filename) {
return __awaiter(this, void 0, void 0, function* () {
return yield channel.sendRequest(IAutoRestPluginInitiator_Types.ReadFile, sessionId, filename);
});
},
GetValue(key) {
return __awaiter(this, void 0, void 0, function* () {
return yield channel.sendRequest(IAutoRestPluginInitiator_Types.GetValue, sessionId, key);
});
},
ListInputs() {
return __awaiter(this, void 0, void 0, function* () {
return yield channel.sendRequest(IAutoRestPluginInitiator_Types.ListInputs, sessionId);
});
},
WriteFile(filename, content, sourceMap) {
channel.sendNotification(IAutoRestPluginInitiator_Types.WriteFile, sessionId, filename, content, sourceMap);
},
Message(message) {
channel.sendNotification(IAutoRestPluginInitiator_Types.Message, sessionId, message);
}
});
return true;
}
catch (e) {
channel.sendNotification(IAutoRestPluginInitiator_Types.Message, sessionId, {
Channel: "fatal",
Text: "" + e,
Details: e
});
return false;
}
}));
// activate
channel.listen();
});
}
}
exports.AutoRestExtension = AutoRestExtension;

2
dist/lib/types.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

1
index.ts Normal file
Просмотреть файл

@ -0,0 +1 @@
export { AutoRestExtension } from "./lib/extension-base";

95
lib/extension-base.ts Normal file
Просмотреть файл

@ -0,0 +1,95 @@
import {
createMessageConnection, Logger,
RequestType0, RequestType1, RequestType2,
NotificationType2, NotificationType4
} from "vscode-jsonrpc";
import { Readable } from "stream";
import { Mapping, Message, RawSourceMap } from "./types";
module IAutoRestPluginTarget_Types {
export const GetPluginNames = new RequestType0<string[], Error, void>("GetPluginNames");
export const Process = new RequestType2<string, string, boolean, Error, void>("Process");
}
interface IAutoRestPluginTarget {
GetPluginNames(): Promise<string[]>;
Process(pluginName: string, sessionId: string): Promise<boolean>;
}
module IAutoRestPluginInitiator_Types {
export const ReadFile = new RequestType2<string, string, string, Error, void>("ReadFile");
export const GetValue = new RequestType2<string, string, any, Error, void>("GetValue");
export const ListInputs = new RequestType1<string, string[], Error, void>("ListInputs");
export const WriteFile = new NotificationType4<string, string, string, Mapping[] | RawSourceMap | undefined, void>("WriteFile");
export const Message = new NotificationType2<string, Message, void>("Message");
}
interface IAutoRestPluginInitiator {
ReadFile(filename: string): Promise<string>;
GetValue(key: string): Promise<any>;
ListInputs(): Promise<string[]>;
WriteFile(filename: string, content: string, sourceMap?: Mapping[] | RawSourceMap): void;
Message(message: Message): void;
}
type AutoRestPluginHandler = (initiator: IAutoRestPluginInitiator) => Promise<void>;
export class AutoRestExtension {
private readonly plugins: { [name: string]: AutoRestPluginHandler } = {};
public Add(name: string, handler: AutoRestPluginHandler): void {
this.plugins[name] = handler;
}
public async Run(input: NodeJS.ReadableStream = process.stdin, output: NodeJS.WritableStream = process.stdout): Promise<void> {
// connection setup
const channel = createMessageConnection(
input,
output,
{
error(message) { console.error("error: ", message); },
info(message) { console.error("info: ", message); },
log(message) { console.error("log: ", message); },
warn(message) { console.error("warn: ", message); }
}
);
channel.onRequest(IAutoRestPluginTarget_Types.GetPluginNames, async () => Object.keys(this.plugins));
channel.onRequest(IAutoRestPluginTarget_Types.Process, async (pluginName: string, sessionId: string) => {
try {
const handler = this.plugins[pluginName];
if (!handler) {
throw new Error(`Plugin host could not find requested plugin '${pluginName}'.`);
}
await handler({
async ReadFile(filename: string): Promise<string> {
return await channel.sendRequest(IAutoRestPluginInitiator_Types.ReadFile, sessionId, filename);
},
async GetValue(key: string): Promise<any> {
return await channel.sendRequest(IAutoRestPluginInitiator_Types.GetValue, sessionId, key);
},
async ListInputs(): Promise<string[]> {
return await channel.sendRequest(IAutoRestPluginInitiator_Types.ListInputs, sessionId);
},
WriteFile(filename: string, content: string, sourceMap?: Mapping[] | RawSourceMap): void {
channel.sendNotification(IAutoRestPluginInitiator_Types.WriteFile, sessionId, filename, content, sourceMap);
},
Message(message: Message): void {
channel.sendNotification(IAutoRestPluginInitiator_Types.Message, sessionId, message);
}
});
return true;
} catch (e) {
channel.sendNotification(IAutoRestPluginInitiator_Types.Message, sessionId, <Message>{
Channel: "fatal" as any,
Text: "" + e,
Details: e
});
return false;
}
});
// activate
channel.listen();
}
}

37
lib/types.ts Normal file
Просмотреть файл

@ -0,0 +1,37 @@
/* line: 1-based, column: 0-based */
export type Position = {
line: number; // 1-based
column: number; // 0-based
} | { path?: JsonPath };
export type JsonPath = (string | number)[];
export interface SourceLocation {
document: string;
Position: Position;
}
export interface Message {
Channel: "information" | "warning" | "error" | "debug" | "verbose";
Key?: Iterable<string>;
Details?: any;
Text: string;
Source?: Array<SourceLocation>;
}
export interface RawSourceMap {
file?: string;
sourceRoot?: string;
version: string;
sources: string[];
names: string[];
sourcesContent?: string[];
mappings: string;
}
export interface Mapping {
generated: Position;
original: Position;
source: string;
name?: string;
}

22
package.json Normal file
Просмотреть файл

@ -0,0 +1,22 @@
{
"name": "autorest-extension-base",
"version": "0.1.0",
"description": "Library for easily creating AutoRest extensions",
"main": "dist/index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/olydis/autorest-extension-base.git"
},
"keywords": [
"autorest",
"extension"
],
"author": "Microsoft Corporation",
"license": "MIT",
"devDependencies": {
"@types/node": "^7.0.18"
},
"dependencies": {
"vscode-jsonrpc": "^3.2.0"
}
}

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

@ -1,14 +1,41 @@
# Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
# Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
# AutoRest Extension Base
Allows to easily create an AutoRest extension.
See https://github.com/olydis/autorest-extension-helloworld for an example of how to reference and use this package. We recommend using *that* as a starting point.
## Usage
``` JavaScript
import { AutoRestExtension } from "autorest-extension-base";
const extension = new AutoRestExtension();
extension.Add("plugin-name", async autoRestApi => {
// plugin implementation
// Available functions:
// * Information retrieval:
// autoRestApi.ListInputs
// autoRestApi.ReadFile
// autoRestApi.GetValue
// * Information submission:
// autoRestApi.WriteFile
// autoRestApi.Message
});
extension.Run();
```

17
tsconfig.json Normal file
Просмотреть файл

@ -0,0 +1,17 @@
{
"compilerOptions": {
"lib": [
"es2016",
"dom"
],
"module": "commonjs",
"outDir": "dist",
"types": [
"node"
],
"target": "es2016"
},
"exclude": [
"node_modules"
]
}