GoogleOauth2.0 First implementation

First try for GoogleOauth2.0
This commit is contained in:
Georg Reisinger
2018-10-26 14:02:15 +02:00
parent 216a04e233
commit b171f1646c
1880 changed files with 912953 additions and 7 deletions

View File

@ -0,0 +1,59 @@
import { AxiosAdapter, AxiosProxyConfig, AxiosRequestConfig, AxiosResponse, AxiosTransformer, CancelToken } from 'axios';
import { OAuth2Client } from 'google-auth-library';
import { Endpoint } from './endpoint';
export interface APIRequestParams<T = any> {
options: AxiosRequestConfig;
params: T;
requiredParams: string[];
pathParams: string[];
context: APIRequestContext;
mediaUrl?: string | null;
}
export interface GoogleConfigurable {
_options: GlobalOptions;
}
export interface APIRequestContext {
google?: GoogleConfigurable;
_options: GlobalOptions;
}
/**
* This interface is a mix of the AxiosRequestConfig options
* and our `auth: OAuth2Client|string` options. We need to redefine
* the interface here because the `auth` property already exists
* on AxiosRequestConfig, and uses an entirely different type.
*/
export interface GlobalOptions {
url?: string;
method?: string;
baseURL?: string;
transformRequest?: AxiosTransformer | AxiosTransformer[];
transformResponse?: AxiosTransformer | AxiosTransformer[];
headers?: any;
params?: any;
paramsSerializer?: (params: any) => string;
data?: any;
timeout?: number;
withCredentials?: boolean;
adapter?: AxiosAdapter;
auth?: OAuth2Client | string;
responseType?: string;
xsrfCookieName?: string;
xsrfHeaderName?: string;
onUploadProgress?: (progressEvent: any) => void;
onDownloadProgress?: (progressEvent: any) => void;
maxContentLength?: number;
validateStatus?: (status: number) => boolean;
maxRedirects?: number;
httpAgent?: any;
httpsAgent?: any;
proxy?: AxiosProxyConfig | false;
cancelToken?: CancelToken;
}
export interface MethodOptions extends AxiosRequestConfig {
rootUrl?: string;
}
export interface ServiceOptions extends GlobalOptions {
version?: string;
}
export declare type BodyResponseCallback<T> = (err: Error | null, res?: AxiosResponse<T> | null) => void;
export declare type APIEndpoint = Readonly<Endpoint & any>;

View File

@ -0,0 +1,15 @@
"use strict";
// Copyright 2018, Google, LLC.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=api.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/api.ts"],"names":[],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC"}

View File

@ -0,0 +1,4 @@
import { GoogleConfigurable, ServiceOptions } from '.';
export declare function getAPI<T>(api: string, options: ServiceOptions | string, versions: {
[index: string]: any;
}, context?: GoogleConfigurable): T;

View File

@ -0,0 +1,40 @@
"use strict";
// Copyright 2018, Google, LLC.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Object.defineProperty(exports, "__esModule", { value: true });
function getAPI(api, options,
// tslint:disable-next-line no-any
versions, context) {
let version;
if (typeof options === 'string') {
version = options;
options = {};
}
else if (typeof options === 'object') {
version = options.version;
delete options.version;
}
else {
throw new Error('Argument error: Accepts only string or object');
}
try {
const ctr = versions[version];
const ep = new ctr(options, context);
return Object.freeze(ep);
}
catch (e) {
throw new Error(`Unable to load endpoint ${api}("${version}"): ${e.message}`);
}
}
exports.getAPI = getAPI;
//# sourceMappingURL=apiIndex.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"apiIndex.js","sourceRoot":"","sources":["../../src/apiIndex.ts"],"names":[],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAIjC,SAAgB,MAAM,CAClB,GAAW,EAAE,OAA8B;AAC3C,kCAAkC;AAClC,QAAgC,EAAE,OAA4B;IAChE,IAAI,OAAe,CAAC;IACpB,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAC/B,OAAO,GAAG,OAAO,CAAC;QAClB,OAAO,GAAG,EAAE,CAAC;KACd;SAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QACtC,OAAO,GAAG,OAAO,CAAC,OAAQ,CAAC;QAC3B,OAAO,OAAO,CAAC,OAAO,CAAC;KACxB;SAAM;QACL,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;KAClE;IACD,IAAI;QACF,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACrC,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,CAAM,CAAC;KAC/B;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,IAAI,KAAK,CACX,2BAA2B,GAAG,KAAK,OAAO,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;KACnE;AACH,CAAC;AAtBD,wBAsBC"}

View File

@ -0,0 +1,10 @@
import { AxiosPromise } from 'axios';
import { BodyResponseCallback } from 'google-auth-library/build/src/transporters';
import { APIRequestParams } from './api';
/**
* Create and send request to Google API
* @param parameters Parameters used to form request
* @param callback Callback when request finished or error found
*/
export declare function createAPIRequest<T>(parameters: APIRequestParams): AxiosPromise<T>;
export declare function createAPIRequest<T>(parameters: APIRequestParams, callback: BodyResponseCallback<T>): void;

View File

@ -0,0 +1,249 @@
"use strict";
// Copyright 2014-2016, Google, Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
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 google_auth_library_1 = require("google-auth-library");
const qs = require("qs");
const stream = require("stream");
const urlTemplate = require("url-template");
const uuid = require("uuid");
const maxContentLength = Math.pow(2, 31);
// tslint:disable-next-line no-var-requires
const pkg = require('../../package.json');
const USER_AGENT = `google-api-nodejs-client/${pkg.version} (gzip)`;
function isReadableStream(obj) {
return obj instanceof stream.Readable && typeof obj._read === 'function';
}
function getMissingParams(params, required) {
const missing = new Array();
required.forEach(param => {
// Is the required param in the params object?
if (params[param] === undefined) {
missing.push(param);
}
});
// If there are any required params missing, return their names in array,
// otherwise return null
return missing.length > 0 ? missing : null;
}
function createAPIRequest(parameters, callback) {
if (callback) {
createAPIRequestAsync(parameters).then(r => callback(null, r), callback);
}
else {
return createAPIRequestAsync(parameters);
}
}
exports.createAPIRequest = createAPIRequest;
function createAPIRequestAsync(parameters) {
return __awaiter(this, void 0, void 0, function* () {
let params = parameters.params;
const options = Object.assign({}, parameters.options);
// Create a new params object so it can no longer be modified from outside
// code Also support global and per-client params, but allow them to be
// overriden per-request
const topOptions = parameters.context.google ?
parameters.context.google._options.params :
{};
params = Object.assign({}, // New base object
topOptions, // Global params
parameters.context._options.params, // Per-client params
params // API call params
);
const media = params.media || {};
/**
* In a previous version of this API, the request body was stuffed in a field
* named `resource`. This caused lots of problems, because it's not uncommon
* to have an actual named parameter required which is also named `resource`.
* This mean that users would have to use `resource_` in those cases, which
* pretty much nobody figures out on their own. The request body is now
* documented as being in the `requestBody` property, but we also need to keep
* using `resource` for reasons of back-compat. Cases that need to be covered
* here:
* - user provides just a `resource` with a request body
* - user provides both a `resource` and a `resource_`
* - user provides just a `requestBody`
* - user provides both a `requestBody` and a `resource`
*/
const resource = params.requestBody ? params.requestBody : params.resource;
if (!params.requestBody && params.resource) {
delete params.resource;
}
delete params.requestBody;
let authClient = params.auth || parameters.context._options.auth ||
(parameters.context.google ? parameters.context.google._options.auth :
null);
const defaultMime = typeof media.body === 'string' ?
'text/plain' :
'application/octet-stream';
delete params.media;
delete params.auth;
// Grab headers from user provided options
const headers = params.headers || {};
delete params.headers;
// Un-alias parameters that were modified due to conflicts with reserved names
Object.keys(params).forEach(key => {
if (key.slice(-1) === '_') {
const newKey = key.slice(0, -1);
params[newKey] = params[key];
delete params[key];
}
});
// Check for missing required parameters in the API request
const missingParams = getMissingParams(params, parameters.requiredParams);
if (missingParams) {
// Some params are missing - stop further operations and inform the
// developer which required params are not included in the request
throw new Error('Missing required parameters: ' + missingParams.join(', '));
}
// Parse urls
if (options.url) {
options.url = urlTemplate.parse(options.url).expand(params);
}
if (parameters.mediaUrl) {
parameters.mediaUrl = urlTemplate.parse(parameters.mediaUrl).expand(params);
}
// When forming the querystring, override the serializer so that array
// values are serialized like this:
// myParams: ['one', 'two'] ---> 'myParams=one&myParams=two'
// This serializer also encodes spaces in the querystring as `%20`,
// whereas the default serializer in axios encodes to a `+`.
options.paramsSerializer = (params) => {
return qs.stringify(params, { arrayFormat: 'repeat' });
};
// delete path parameters from the params object so they do not end up in
// query
parameters.pathParams.forEach(param => {
delete params[param];
});
// if authClient is actually a string, use it as an API KEY
if (typeof authClient === 'string') {
params.key = params.key || authClient;
authClient = undefined;
}
if (parameters.mediaUrl && media.body) {
options.url = parameters.mediaUrl;
if (resource) {
// Axios doesn't support multipart/related uploads, so it has to
// be implemented here.
params.uploadType = 'multipart';
const multipart = [
{ 'Content-Type': 'application/json', body: JSON.stringify(resource) }, {
'Content-Type': media.mimeType || (resource && resource.mimeType) || defaultMime,
body: media.body // can be a readable stream or raw string!
}
];
const boundary = uuid.v4();
const finale = `--${boundary}--`;
const rStream = new stream.PassThrough();
const pStream = new ProgressStream();
const isStream = isReadableStream(multipart[1].body);
headers['Content-Type'] = `multipart/related; boundary=${boundary}`;
for (const part of multipart) {
const preamble = `--${boundary}\r\nContent-Type: ${part['Content-Type']}\r\n\r\n`;
rStream.push(preamble);
if (typeof part.body === 'string') {
rStream.push(part.body);
rStream.push('\r\n');
}
else {
// Axios does not natively support onUploadProgress in node.js.
// Pipe through the pStream first to read the number of bytes read
// for the purpose of tracking progress.
pStream.on('progress', bytesRead => {
if (options.onUploadProgress) {
options.onUploadProgress({ bytesRead });
}
});
part.body.pipe(pStream).pipe(rStream, { end: false });
part.body.on('end', () => {
rStream.push('\r\n');
rStream.push(finale);
rStream.push(null);
});
}
}
if (!isStream) {
rStream.push(finale);
rStream.push(null);
}
options.data = rStream;
}
else {
params.uploadType = 'media';
Object.assign(headers, { 'Content-Type': media.mimeType || defaultMime });
options.data = media.body;
}
}
else {
options.data = resource || undefined;
}
options.headers = headers;
options.params = params;
// We need to set a default content size, or the max defaults
// to 10MB. Setting to 2GB by default.
// https://github.com/google/google-api-nodejs-client/issues/991
options.maxContentLength = options.maxContentLength || maxContentLength;
options.headers['Accept-Encoding'] = 'gzip';
options.headers['User-Agent'] = USER_AGENT;
// By default Axios treats any 2xx as valid, and all non 2xx status
// codes as errors. This is a problem for HTTP 304s when used along
// with an eTag.
if (!options.validateStatus) {
options.validateStatus = (status) => {
return (status >= 200 && status < 300) || status === 304;
};
}
// Combine the AxiosRequestConfig options passed with this specific
// API call witht the global options configured at the API Context
// level, or at the global level.
const mergedOptions = Object.assign({}, (parameters.context.google ? parameters.context.google._options : {}), parameters.context._options, options);
delete mergedOptions.auth; // is overridden by our auth code
// Perform the HTTP request. NOTE: this function used to return a
// mikeal/request object. Since the transition to Axios, the method is
// now void. This may be a source of confusion for users upgrading from
// version 24.0 -> 25.0 or up.
if (authClient && typeof authClient === 'object') {
return authClient.request(mergedOptions);
}
else {
return (new google_auth_library_1.DefaultTransporter()).request(mergedOptions);
}
});
}
/**
* Basic Passthrough Stream that records the number of bytes read
* every time the cursor is moved.
*/
class ProgressStream extends stream.Transform {
constructor() {
super(...arguments);
this.bytesRead = 0;
}
// tslint:disable-next-line: no-any
_transform(chunk, encoding, callback) {
this.bytesRead += chunk.length;
this.emit('progress', this.bytesRead);
this.push(chunk);
callback();
}
}
//# sourceMappingURL=apirequest.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,42 @@
import { GlobalOptions } from './api';
import { Endpoint } from './endpoint';
export declare type EndpointCreator = (options: GlobalOptions, google: {}) => Endpoint;
export interface DiscoveryOptions {
includePrivate?: boolean;
debug?: boolean;
}
export declare class Discovery {
private transporter;
private options;
/**
* Discovery for discovering API endpoints
*
* @param options Options for discovery
*/
constructor(options: DiscoveryOptions);
/**
* Generate and Endpoint from an endpoint schema object.
*
* @param schema The schema from which to generate the Endpoint.
* @return A function that creates an endpoint.
*/
private makeEndpoint;
/**
* Log output of generator. Works just like console.log
*/
private log;
/**
* Generate all APIs and return as in-memory object.
* @param discoveryUrl
*/
discoverAllAPIs(discoveryUrl: string): Promise<{}>;
/**
* Generate API file given discovery URL
*
* @param apiDiscoveryUrl URL or filename of discovery doc for API
* @returns A promise that resolves with a function that creates the endpoint
*/
discoverAPI(apiDiscoveryUrl: string | {
url: string;
}): Promise<EndpointCreator>;
}

View File

@ -0,0 +1,152 @@
"use strict";
// Copyright 2014-2016, Google, Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
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 fs = require("fs");
const google_auth_library_1 = require("google-auth-library");
const pify = require("pify");
const url = require("url");
const util = require("util");
const apirequest_1 = require("./apirequest");
const endpoint_1 = require("./endpoint");
const fsp = pify(fs);
class Discovery {
/**
* Discovery for discovering API endpoints
*
* @param options Options for discovery
*/
constructor(options) {
this.transporter = new google_auth_library_1.DefaultTransporter();
this.options = options || {};
}
/**
* Generate and Endpoint from an endpoint schema object.
*
* @param schema The schema from which to generate the Endpoint.
* @return A function that creates an endpoint.
*/
makeEndpoint(schema) {
return (options) => {
const ep = new endpoint_1.Endpoint(options);
ep.applySchema(ep, schema, schema, ep);
return ep;
};
}
/**
* Log output of generator. Works just like console.log
*/
log(...args) {
if (this.options && this.options.debug) {
console.log.apply(this, arguments);
}
}
/**
* Generate all APIs and return as in-memory object.
* @param discoveryUrl
*/
discoverAllAPIs(discoveryUrl) {
return __awaiter(this, void 0, void 0, function* () {
const headers = this.options.includePrivate ? {} : { 'X-User-Ip': '0.0.0.0' };
const res = yield this.transporter.request({ url: discoveryUrl, headers });
const items = res.data.items;
const apis = yield Promise.all(items.map((api) => __awaiter(this, void 0, void 0, function* () {
const endpointCreator = yield this.discoverAPI(api.discoveryRestUrl);
return { api, endpointCreator };
})));
const versionIndex = {};
// tslint:disable-next-line no-any
const apisIndex = {};
for (const set of apis) {
if (!apisIndex[set.api.name]) {
versionIndex[set.api.name] = {};
apisIndex[set.api.name] = (options) => {
const type = typeof options;
let version;
if (type === 'string') {
version = options;
options = {};
}
else if (type === 'object') {
version = options.version;
delete options.version;
}
else {
throw new Error('Argument error: Accepts only string or object');
}
try {
const ep =
// tslint:disable-next-line: no-any
set.endpointCreator(options, this);
return Object.freeze(ep); // create new & freeze
}
catch (e) {
throw new Error(util.format('Unable to load endpoint %s("%s"): %s', set.api.name, version, e.message));
}
};
}
versionIndex[set.api.name][set.api.version] = set.endpointCreator;
}
return apisIndex;
});
}
/**
* Generate API file given discovery URL
*
* @param apiDiscoveryUrl URL or filename of discovery doc for API
* @returns A promise that resolves with a function that creates the endpoint
*/
discoverAPI(apiDiscoveryUrl) {
return __awaiter(this, void 0, void 0, function* () {
if (typeof apiDiscoveryUrl === 'string') {
const parts = url.parse(apiDiscoveryUrl);
if (apiDiscoveryUrl && !parts.protocol) {
this.log('Reading from file ' + apiDiscoveryUrl);
const file = yield fsp.readFile(apiDiscoveryUrl, { encoding: 'utf8' });
return this.makeEndpoint(JSON.parse(file));
}
else {
this.log('Requesting ' + apiDiscoveryUrl);
const res = yield this.transporter.request({ url: apiDiscoveryUrl });
return this.makeEndpoint(res.data);
}
}
else {
const options = apiDiscoveryUrl;
this.log('Requesting ' + options.url);
const url = options.url;
delete options.url;
const parameters = {
options: { url, method: 'GET' },
requiredParams: [],
pathParams: [],
params: options,
context: { google: { _options: {} }, _options: {} }
};
const pcr = pify(apirequest_1.createAPIRequest);
const res = yield pcr(parameters);
return this.makeEndpoint(res.data);
}
});
}
}
exports.Discovery = Discovery;
//# sourceMappingURL=discovery.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/discovery.ts"],"names":[],"mappings":"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"}

View File

@ -0,0 +1,42 @@
import { APIRequestContext, GlobalOptions } from './api';
import { Schema, SchemaResource } from './schema';
export interface Target {
[index: string]: {};
}
export declare class Endpoint implements Target, APIRequestContext {
_options: GlobalOptions;
google: any;
[index: string]: {};
constructor(options: {});
/**
* Given a schema, add methods and resources to a target.
*
* @param {object} target The target to which to apply the schema.
* @param {object} rootSchema The top-level schema, so we don't lose track of it
* during recursion.
* @param {object} schema The current schema from which to extract methods and
* resources.
* @param {object} context The context to add to each method.
*/
applySchema(target: Target, rootSchema: Schema, schema: SchemaResource, context: APIRequestContext): void;
/**
* Given a schema, add methods to a target.
*
* @param {object} target The target to which to apply the methods.
* @param {object} rootSchema The top-level schema, so we don't lose track of it
* during recursion.
* @param {object} schema The current schema from which to extract methods.
* @param {object} context The context to add to each method.
*/
private applyMethodsFromSchema;
/**
* Given a method schema, add a method to a target.
*
* @param target The target to which to add the method.
* @param schema The top-level schema that contains the rootUrl, etc.
* @param method The method schema from which to generate the method.
* @param context The context to add to the method.
*/
private makeMethod;
private getPathParams;
}

View File

@ -0,0 +1,124 @@
"use strict";
// Copyright 2018, Google, LLC.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Object.defineProperty(exports, "__esModule", { value: true });
const apirequest_1 = require("./apirequest");
class Endpoint {
constructor(options) {
this._options = options || {};
}
/**
* Given a schema, add methods and resources to a target.
*
* @param {object} target The target to which to apply the schema.
* @param {object} rootSchema The top-level schema, so we don't lose track of it
* during recursion.
* @param {object} schema The current schema from which to extract methods and
* resources.
* @param {object} context The context to add to each method.
*/
applySchema(target, rootSchema, schema, context) {
this.applyMethodsFromSchema(target, rootSchema, schema, context);
if (schema.resources) {
for (const resourceName in schema.resources) {
if (schema.resources.hasOwnProperty(resourceName)) {
const resource = schema.resources[resourceName];
if (!target[resourceName]) {
target[resourceName] = {};
}
this.applySchema(target[resourceName], rootSchema, resource, context);
}
}
}
}
/**
* Given a schema, add methods to a target.
*
* @param {object} target The target to which to apply the methods.
* @param {object} rootSchema The top-level schema, so we don't lose track of it
* during recursion.
* @param {object} schema The current schema from which to extract methods.
* @param {object} context The context to add to each method.
*/
applyMethodsFromSchema(target, rootSchema, schema, context) {
if (schema.methods) {
for (const name in schema.methods) {
if (schema.methods.hasOwnProperty(name)) {
const method = schema.methods[name];
target[name] = this.makeMethod(rootSchema, method, context);
}
}
}
}
/**
* Given a method schema, add a method to a target.
*
* @param target The target to which to add the method.
* @param schema The top-level schema that contains the rootUrl, etc.
* @param method The method schema from which to generate the method.
* @param context The context to add to the method.
*/
makeMethod(schema, method, context) {
return (paramsOrCallback, callback) => {
const params = typeof paramsOrCallback === 'function' ? {} : paramsOrCallback;
callback =
typeof paramsOrCallback === 'function' ? paramsOrCallback : callback;
const schemaUrl = buildurl(schema.rootUrl + schema.servicePath + method.path);
const parameters = {
options: {
url: schemaUrl.substring(1, schemaUrl.length - 1),
method: method.httpMethod
},
params,
requiredParams: method.parameterOrder || [],
pathParams: this.getPathParams(method.parameters),
context
};
if (method.mediaUpload && method.mediaUpload.protocols &&
method.mediaUpload.protocols.simple &&
method.mediaUpload.protocols.simple.path) {
const mediaUrl = buildurl(schema.rootUrl + method.mediaUpload.protocols.simple.path);
parameters.mediaUrl = mediaUrl.substring(1, mediaUrl.length - 1);
}
if (!callback) {
return apirequest_1.createAPIRequest(parameters);
}
apirequest_1.createAPIRequest(parameters, callback);
return;
};
}
getPathParams(params) {
const pathParams = new Array();
if (typeof params !== 'object') {
params = {};
}
Object.keys(params).forEach(key => {
if (params[key].location === 'path') {
pathParams.push(key);
}
});
return pathParams;
}
}
exports.Endpoint = Endpoint;
/**
* Build a string used to create a URL from the discovery doc provided URL.
* replace double slashes with single slash (except in https://)
* @private
* @param input URL to build from
* @return Resulting built URL
*/
function buildurl(input) {
return input ? `'${input}'`.replace(/([^:]\/)\/+/g, '$1') : '';
}
//# sourceMappingURL=endpoint.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"endpoint.js","sourceRoot":"","sources":["../../src/endpoint.ts"],"names":[],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAKjC,6CAA8C;AAO9C,MAAa,QAAQ;IAMnB,YAAY,OAAW;QACrB,IAAI,CAAC,QAAQ,GAAG,OAAO,IAAI,EAAE,CAAC;IAChC,CAAC;IAED;;;;;;;;;OASG;IACH,WAAW,CACP,MAAc,EAAE,UAAkB,EAAE,MAAsB,EAC1D,OAA0B;QAC5B,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QACjE,IAAI,MAAM,CAAC,SAAS,EAAE;YACpB,KAAK,MAAM,YAAY,IAAI,MAAM,CAAC,SAAS,EAAE;gBAC3C,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE;oBACjD,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;oBAChD,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE;wBACzB,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;qBAC3B;oBACD,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;iBACvE;aACF;SACF;IACH,CAAC;IAED;;;;;;;;OAQG;IACK,sBAAsB,CAC1B,MAAc,EAAE,UAAkB,EAAE,MAAsB,EAC1D,OAA0B;QAC5B,IAAI,MAAM,CAAC,OAAO,EAAE;YAClB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE;gBACjC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;oBACvC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBACpC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;iBAC7D;aACF;SACF;IACH,CAAC;IAED;;;;;;;OAOG;IACK,UAAU,CACd,MAAc,EAAE,MAAoB,EAAE,OAA0B;QAClE,OAAO,CAAC,gBAA6C,EAC7C,QAAmC,EAAE,EAAE;YAC7C,MAAM,MAAM,GACR,OAAO,gBAAgB,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC;YACnE,QAAQ;gBACJ,OAAO,gBAAgB,KAAK,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC;YACzE,MAAM,SAAS,GACX,QAAQ,CAAC,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;YAEhE,MAAM,UAAU,GAAqB;gBACnC,OAAO,EAAE;oBACP,GAAG,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjD,MAAM,EAAE,MAAM,CAAC,UAAU;iBAC1B;gBACD,MAAM;gBACN,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,EAAE;gBAC3C,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC;gBACjD,OAAO;aACR,CAAC;YAEF,IAAI,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC,SAAS;gBAClD,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM;gBACnC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE;gBAC5C,MAAM,QAAQ,GACV,QAAQ,CAAC,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACxE,UAAU,CAAC,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;aAClE;YAED,IAAI,CAAC,QAAQ,EAAE;gBACb,OAAO,6BAAgB,CAAC,UAAU,CAAC,CAAC;aACrC;YACD,6BAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YACvC,OAAO;QACT,CAAC,CAAC;IACJ,CAAC;IAEO,aAAa,CAAC,MAAyB;QAC7C,MAAM,UAAU,GAAG,IAAI,KAAK,EAAU,CAAC;QACvC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;YAC9B,MAAM,GAAG,EAAE,CAAC;SACb;QACD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YAChC,IAAI,MAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,MAAM,EAAE;gBACpC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;aACtB;QACH,CAAC,CAAC,CAAC;QACH,OAAO,UAAU,CAAC;IACpB,CAAC;CACF;AArHD,4BAqHC;AAED;;;;;;GAMG;AACH,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACjE,CAAC"}

View File

@ -0,0 +1,6 @@
export { APIEndpoint, APIRequestContext, APIRequestParams, BodyResponseCallback, GlobalOptions, GoogleConfigurable, MethodOptions, ServiceOptions } from './api';
export { getAPI } from './apiIndex';
export { createAPIRequest } from './apirequest';
export { Discovery, DiscoveryOptions, EndpointCreator } from './discovery';
export { Endpoint, Target } from './endpoint';
export { FragmentResponse, HttpMethod, ParameterFormat, Schema, SchemaItem, SchemaItems, SchemaMethod, SchemaMethods, SchemaParameter, SchemaParameters, SchemaResource, SchemaResources, Schemas, SchemaType } from './schema';

View File

@ -0,0 +1,23 @@
"use strict";
// Copyright 2018, Google, LLC.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Object.defineProperty(exports, "__esModule", { value: true });
var apiIndex_1 = require("./apiIndex");
exports.getAPI = apiIndex_1.getAPI;
var apirequest_1 = require("./apirequest");
exports.createAPIRequest = apirequest_1.createAPIRequest;
var discovery_1 = require("./discovery");
exports.Discovery = discovery_1.Discovery;
var endpoint_1 = require("./endpoint");
exports.Endpoint = endpoint_1.Endpoint;
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAGjC,uCAAkC;AAA1B,4BAAA,MAAM,CAAA;AACd,2CAA8C;AAAtC,wCAAA,gBAAgB,CAAA;AACxB,yCAAyE;AAAjE,gCAAA,SAAS,CAAA;AACjB,uCAA4C;AAApC,8BAAA,QAAQ,CAAA"}

View File

@ -0,0 +1,123 @@
/**
* These are a collection of interfaces that represent the GoogleApis
* Discovery json formats.
*/
export interface Schemas {
discoveryVersion: string;
kind: string;
items: Schema[];
}
export interface Schema {
auth: {
oauth2: {
scopes: {
[index: string]: {
description: string;
};
};
};
};
basePath: string;
baseUrl: string;
batchPath: string;
description: string;
discoveryVersion: string;
discoveryRestUrl: string;
documentationLink: string;
etag: string;
icons: {
x16: string;
x32: string;
};
id: string;
kind: string;
methods: SchemaMethods;
name: string;
ownerDomain: string;
ownerName: string;
parameters: SchemaParameters;
protocol: string;
resources: SchemaResources;
revision: string;
rootUrl: string;
schemas: SchemaItems;
servicePath: string;
title: string;
version: string;
}
export interface SchemaResources {
[index: string]: SchemaResource;
}
export interface SchemaResource {
methods?: SchemaMethods;
resources?: SchemaResources;
}
export interface SchemaItems {
[index: string]: SchemaItem;
}
export interface SchemaItem {
description?: string;
default?: string;
id?: string;
properties?: {
[index: string]: SchemaItem;
};
items?: {
[index: string]: SchemaItem;
};
type?: SchemaType;
format?: ParameterFormat;
$ref?: string;
}
export interface SchemaParameters {
[index: string]: SchemaParameter;
}
export interface SchemaParameter {
default: string;
description: string;
location: string;
enum: string[];
enumDescription: string[];
type: SchemaType;
format: ParameterFormat;
required: boolean;
}
export interface SchemaMethods {
[index: string]: SchemaMethod;
}
export interface SchemaMethod {
description: string;
httpMethod: HttpMethod;
id: string;
parameterOrder?: string[];
parameters?: {
[index: string]: SchemaParameter;
};
path: string;
request: {
$ref: string;
};
response: {
$ref: string;
};
sampleUrl: string;
scopes: string[];
fragment: string;
mediaUpload: {
protocols: {
simple: {
path: string;
};
};
};
}
export interface FragmentResponse {
codeFragment: {
[index: string]: {
fragment: string;
};
};
}
export declare type ParameterFormat = 'int32';
export declare type HttpMethod = 'GET' | 'PATCH' | 'PUT';
export declare type SchemaType = 'object' | 'integer' | 'string' | 'array' | 'boolean';

View File

@ -0,0 +1,15 @@
"use strict";
// Copyright 2018, Google, LLC.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=schema.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/schema.ts"],"names":[],"mappings":";AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,gDAAgD;AAChD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC"}