initial commit of actions
This commit is contained in:
commit
949ece5785
44660 changed files with 12034344 additions and 0 deletions
30
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/gateway.d.ts
generated
vendored
Normal file
30
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/gateway.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import { FileDescriptorProto } from "@protobuf-ts/plugin-framework";
|
||||
import { MatchFunction } from "path-to-regexp";
|
||||
export declare enum Pattern {
|
||||
POST = "post",
|
||||
GET = "get",
|
||||
PATCH = "patch",
|
||||
PUT = "put",
|
||||
DELETE = "delete"
|
||||
}
|
||||
export interface HttpRoute {
|
||||
serviceName: string;
|
||||
methodName: string;
|
||||
packageName: string;
|
||||
matchingPath: string;
|
||||
matcher: MatchFunction;
|
||||
httpMethod: Pattern;
|
||||
bodyKey?: string;
|
||||
responseBodyKey?: string;
|
||||
additionalBindings?: HttpRoute;
|
||||
}
|
||||
export declare type HttpRulePattern = {
|
||||
[key in Pattern]: string;
|
||||
};
|
||||
export interface HttpOption extends HttpRulePattern {
|
||||
body: string;
|
||||
responseBody: string;
|
||||
additional_bindings: HttpOption;
|
||||
}
|
||||
export declare function genGateway(ctx: any, files: readonly FileDescriptorProto[]): Promise<string>;
|
||||
export declare function getMethod(httpSpec: HttpOption): Pattern;
|
||||
113
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/gateway.js
generated
vendored
Normal file
113
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/gateway.js
generated
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
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) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getMethod = exports.genGateway = exports.Pattern = void 0;
|
||||
const fs_1 = require("fs");
|
||||
const ts_poet_1 = require("ts-poet");
|
||||
const path_to_regexp_1 = require("path-to-regexp");
|
||||
const Gateway = ts_poet_1.imp("Gateway@twirp-ts");
|
||||
const GatewayPattern = ts_poet_1.imp("Pattern@twirp-ts");
|
||||
const pathToRegexpMatch = ts_poet_1.imp("match@path-to-regexp");
|
||||
const debug = (content) => fs_1.writeFileSync(__dirname + "/debug.json", JSON.stringify(content, null, 2), "utf-8");
|
||||
var Pattern;
|
||||
(function (Pattern) {
|
||||
Pattern["POST"] = "post";
|
||||
Pattern["GET"] = "get";
|
||||
Pattern["PATCH"] = "patch";
|
||||
Pattern["PUT"] = "put";
|
||||
Pattern["DELETE"] = "delete";
|
||||
})(Pattern = exports.Pattern || (exports.Pattern = {}));
|
||||
function genGateway(ctx, files) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const httpRoutes = files.reduce((all, current) => {
|
||||
current.service.forEach(service => {
|
||||
service.method.forEach((method) => {
|
||||
const options = ctx.interpreter.readOptions(method);
|
||||
if (options && options["google.api.http"]) {
|
||||
const httpSpec = options["google.api.http"];
|
||||
all.push(parseHttpOption(httpSpec, current.package || "", method.name, service.name));
|
||||
if (httpSpec.additional_bindings) {
|
||||
all.push(parseHttpOption(httpSpec.additional_bindings, current.package || "", method.name, service.name));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return all;
|
||||
}, []);
|
||||
return genGatewayHandler(httpRoutes).toStringWithImports();
|
||||
});
|
||||
}
|
||||
exports.genGateway = genGateway;
|
||||
function genGatewayHandler(httpRoute) {
|
||||
const genRoutes = (method) => httpRoute.filter(route => route.httpMethod === method).map(route => {
|
||||
return ts_poet_1.code `
|
||||
{
|
||||
packageName: "${route.packageName}",
|
||||
methodName: "${route.methodName}",
|
||||
serviceName: "${route.serviceName}",
|
||||
httpMethod: "${route.httpMethod}" as ${GatewayPattern},
|
||||
matchingPath: "${route.matchingPath}{:query_string(\\\\?.*)}?",
|
||||
matcher: ${pathToRegexpMatch}("${route.matchingPath}{:query_string(\\\\?.*)}?"),
|
||||
bodyKey: "${route.bodyKey || ""}",
|
||||
responseBodyKey: "${route.responseBodyKey || ""}",
|
||||
},
|
||||
`;
|
||||
});
|
||||
return ts_poet_1.code `
|
||||
export function createGateway() {
|
||||
return new ${Gateway}({
|
||||
post: [${ts_poet_1.joinCode(genRoutes(Pattern.POST), { on: "\n" })}],
|
||||
get: [${ts_poet_1.joinCode(genRoutes(Pattern.GET), { on: "\n" })}],
|
||||
put: [${ts_poet_1.joinCode(genRoutes(Pattern.PUT), { on: "\n" })}],
|
||||
patch: [${ts_poet_1.joinCode(genRoutes(Pattern.PATCH), { on: "\n" })}],
|
||||
delete: [${ts_poet_1.joinCode(genRoutes(Pattern.DELETE), { on: "\n" })}],
|
||||
})
|
||||
}
|
||||
`;
|
||||
}
|
||||
function parseHttpOption(httpOption, packageName, methodName, serviceName) {
|
||||
const httpMethod = getMethod(httpOption);
|
||||
const matchingUrl = httpOption[httpMethod];
|
||||
const matchingPath = matcher(matchingUrl);
|
||||
const httpRoute = {
|
||||
packageName,
|
||||
methodName,
|
||||
serviceName,
|
||||
httpMethod: httpMethod,
|
||||
matchingPath,
|
||||
matcher: path_to_regexp_1.match(matchingPath),
|
||||
bodyKey: httpOption.body,
|
||||
responseBodyKey: httpOption.responseBody,
|
||||
};
|
||||
return httpRoute;
|
||||
}
|
||||
function matcher(url) {
|
||||
return url.split("/").map((urlSegment) => {
|
||||
const matchURLParams = /{([0-9a-zA-Z_-]+)}/.exec(urlSegment);
|
||||
if (matchURLParams && matchURLParams.length > 0) {
|
||||
const paramName = matchURLParams[1];
|
||||
return "{:" + paramName + "}";
|
||||
}
|
||||
else {
|
||||
return urlSegment;
|
||||
}
|
||||
}).join("/");
|
||||
}
|
||||
function getMethod(httpSpec) {
|
||||
const possibleMethods = ["post", "get", "patch", "put", "delete"];
|
||||
for (const method of possibleMethods) {
|
||||
if (method in httpSpec) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
throw new Error(`HTTP method not found`);
|
||||
}
|
||||
exports.getMethod = getMethod;
|
||||
3
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/index-file.d.ts
generated
vendored
Normal file
3
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/index-file.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import { DescriptorRegistry } from "@protobuf-ts/plugin-framework";
|
||||
import { File } from "../file";
|
||||
export declare function genIndexFile(registry: DescriptorRegistry, files: File[]): File;
|
||||
29
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/index-file.js
generated
vendored
Normal file
29
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/index-file.js
generated
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.genIndexFile = void 0;
|
||||
const file_1 = require("../file");
|
||||
function genIndexFile(registry, files) {
|
||||
const fileToExport = registry.allFiles()
|
||||
.filter((fileDescriptor) => {
|
||||
let hasExports = false;
|
||||
registry.visitTypes(fileDescriptor, descriptor => {
|
||||
// we are not interested in synthetic types like map entry messages
|
||||
if (registry.isSyntheticElement(descriptor))
|
||||
return;
|
||||
hasExports = true;
|
||||
});
|
||||
return hasExports;
|
||||
})
|
||||
.map((file => { var _a; return (_a = file.name) === null || _a === void 0 ? void 0 : _a.replace(".proto", ""); }));
|
||||
const compiledFiles = files.filter(file => file.getContent() !== "").map(file => {
|
||||
return file.fileName.replace(".ts", "");
|
||||
});
|
||||
if (compiledFiles.length > 0) {
|
||||
fileToExport.push(...compiledFiles);
|
||||
}
|
||||
const indexFile = new file_1.File('index.ts');
|
||||
return indexFile.setContent(fileToExport.map((fileName) => {
|
||||
return `export * from "./${fileName}";`;
|
||||
}).join("\n"));
|
||||
}
|
||||
exports.genIndexFile = genIndexFile;
|
||||
17
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/open-api.d.ts
generated
vendored
Normal file
17
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/open-api.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { FileDescriptorProto } from "@protobuf-ts/plugin-framework";
|
||||
interface OpenAPIDoc {
|
||||
fileName: string;
|
||||
content: string;
|
||||
}
|
||||
export declare enum OpenAPIType {
|
||||
GATEWAY = 0,
|
||||
TWIRP = 1
|
||||
}
|
||||
/**
|
||||
* Generate twirp compliant OpenAPI doc
|
||||
* @param ctx
|
||||
* @param files
|
||||
* @param type
|
||||
*/
|
||||
export declare function genOpenAPI(ctx: any, files: readonly FileDescriptorProto[], type: OpenAPIType): Promise<OpenAPIDoc[]>;
|
||||
export {};
|
||||
580
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/open-api.js
generated
vendored
Normal file
580
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/open-api.js
generated
vendored
Normal file
|
|
@ -0,0 +1,580 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
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) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.genOpenAPI = exports.OpenAPIType = void 0;
|
||||
const plugin_framework_1 = require("@protobuf-ts/plugin-framework");
|
||||
const yaml = __importStar(require("yaml"));
|
||||
const local_type_name_1 = require("../local-type-name");
|
||||
const gateway_1 = require("./gateway");
|
||||
var OpenAPIType;
|
||||
(function (OpenAPIType) {
|
||||
OpenAPIType[OpenAPIType["GATEWAY"] = 0] = "GATEWAY";
|
||||
OpenAPIType[OpenAPIType["TWIRP"] = 1] = "TWIRP";
|
||||
})(OpenAPIType = exports.OpenAPIType || (exports.OpenAPIType = {}));
|
||||
/**
|
||||
* Generate twirp compliant OpenAPI doc
|
||||
* @param ctx
|
||||
* @param files
|
||||
* @param type
|
||||
*/
|
||||
function genOpenAPI(ctx, files, type) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const documents = [];
|
||||
files.forEach(file => {
|
||||
file.service.forEach((service) => {
|
||||
var _a, _b;
|
||||
const document = {
|
||||
openapi: "3.0.3",
|
||||
info: {
|
||||
title: `${service.name}`,
|
||||
version: "1.0.0",
|
||||
description: genDescription(ctx, service),
|
||||
},
|
||||
paths: type === OpenAPIType.TWIRP ?
|
||||
genTwirpPaths(ctx, file, service) :
|
||||
genGatewayPaths(ctx, file, service),
|
||||
components: genComponents(ctx, service.method),
|
||||
};
|
||||
const fileName = type === OpenAPIType.TWIRP ?
|
||||
`${(_a = service.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()}.twirp.openapi.yaml` :
|
||||
`${(_b = service.name) === null || _b === void 0 ? void 0 : _b.toLowerCase()}.openapi.yaml`;
|
||||
documents.push({
|
||||
fileName,
|
||||
content: yaml.stringify(document),
|
||||
});
|
||||
});
|
||||
});
|
||||
return documents;
|
||||
});
|
||||
}
|
||||
exports.genOpenAPI = genOpenAPI;
|
||||
/**
|
||||
* Generates OpenAPI Twirp URI paths
|
||||
* @param ctx
|
||||
* @param file
|
||||
* @param service
|
||||
*/
|
||||
function genTwirpPaths(ctx, file, service) {
|
||||
return service.method.reduce((paths, method) => {
|
||||
const description = genDescription(ctx, method);
|
||||
paths[`/${file.package ? file.package + "." : ""}${service.name}/${method.name}`] = {
|
||||
post: {
|
||||
summary: description,
|
||||
operationId: `${service.name}_${method.name}`,
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: {
|
||||
$ref: genRef(ctx, method.inputType)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
"200": {
|
||||
description: "OK",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: {
|
||||
$ref: genRef(ctx, method.outputType),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return paths;
|
||||
}, {});
|
||||
}
|
||||
/**
|
||||
* Generates OpenAPI Twrip Gateway URI paths
|
||||
* @param ctx
|
||||
* @param file
|
||||
* @param service
|
||||
*/
|
||||
function genGatewayPaths(ctx, file, service) {
|
||||
const registry = ctx.registry;
|
||||
/**
|
||||
* Build paths recursively
|
||||
* @param method
|
||||
* @param httpSpec
|
||||
* @param paths
|
||||
*/
|
||||
function buildPath(method, httpSpec, paths) {
|
||||
const httpMethod = gateway_1.getMethod(httpSpec);
|
||||
const description = genDescription(ctx, method);
|
||||
const pathItem = {
|
||||
[httpMethod]: {
|
||||
summary: description,
|
||||
operationId: `${service.name}_${method.name}`,
|
||||
}
|
||||
};
|
||||
const inputMessage = registry.resolveTypeName(method.inputType);
|
||||
const outPutMessage = registry.resolveTypeName(method.outputType);
|
||||
// All methods except GET have body
|
||||
if (httpMethod !== gateway_1.Pattern.GET) {
|
||||
pathItem[httpMethod].requestBody = genGatewayBody(ctx, httpSpec, inputMessage);
|
||||
}
|
||||
// All methods might have params
|
||||
pathItem[httpMethod].parameters = genGatewayParams(ctx, httpSpec, inputMessage);
|
||||
pathItem[httpMethod].responses = genGatewayResponse(ctx, httpSpec, outPutMessage);
|
||||
paths[`${httpSpec[httpMethod]}`] = pathItem;
|
||||
if (httpSpec.additional_bindings) {
|
||||
buildPath(method, httpSpec.additional_bindings, paths);
|
||||
}
|
||||
}
|
||||
return service.method.reduce((paths, method) => {
|
||||
const options = ctx.interpreter.readOptions(method);
|
||||
if (!options || options && !options["google.api.http"]) {
|
||||
return paths;
|
||||
}
|
||||
const httpSpec = options["google.api.http"];
|
||||
buildPath(method, httpSpec, paths);
|
||||
return paths;
|
||||
}, {});
|
||||
}
|
||||
/**
|
||||
* Generate OpenAPI Gateway Response
|
||||
* @param ctx
|
||||
* @param httpOptions
|
||||
* @param message
|
||||
*/
|
||||
function genGatewayResponse(ctx, httpOptions, message) {
|
||||
let schema = {};
|
||||
if (httpOptions.responseBody) {
|
||||
schema = {
|
||||
type: "object",
|
||||
properties: {
|
||||
[httpOptions.responseBody]: {
|
||||
$ref: `#/components/schemas/${message.name}`
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
schema = {
|
||||
$ref: `#/components/schemas/${message.name}`
|
||||
};
|
||||
}
|
||||
return {
|
||||
"200": {
|
||||
description: "OK",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate OpenAPI Gateway Response
|
||||
* @param ctx
|
||||
* @param httpOptions
|
||||
* @param message
|
||||
*/
|
||||
function genGatewayBody(ctx, httpOptions, message) {
|
||||
const schema = {};
|
||||
if (httpOptions.body === "*") {
|
||||
schema.$ref = `#/components/schemas/${message.name}`;
|
||||
}
|
||||
else if (httpOptions.body) {
|
||||
const subField = message.field.find(field => field.name === httpOptions.body);
|
||||
if (!subField) {
|
||||
throw new Error(`the body field ${httpOptions.body} cannot be mapped to message ${message.name}`);
|
||||
}
|
||||
schema.properties = {
|
||||
[httpOptions.body]: genField(ctx, subField),
|
||||
};
|
||||
}
|
||||
return {
|
||||
required: true,
|
||||
content: {
|
||||
"application/json": {
|
||||
schema,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generates OpenAPI Gateway Parameters
|
||||
* @param ctx
|
||||
* @param httpOptions
|
||||
* @param message
|
||||
*/
|
||||
function genGatewayParams(ctx, httpOptions, message) {
|
||||
const httpMethod = gateway_1.getMethod(httpOptions);
|
||||
const params = parseUriParams(httpOptions[httpMethod]);
|
||||
const urlParams = message.field
|
||||
.filter((field) => params.find((param) => param === field.name))
|
||||
.map((field) => {
|
||||
return {
|
||||
name: field.name,
|
||||
in: "path",
|
||||
required: true,
|
||||
schema: Object.assign({}, genField(ctx, field))
|
||||
};
|
||||
});
|
||||
if (httpOptions.body === "*") {
|
||||
return urlParams;
|
||||
}
|
||||
const queryString = message.field
|
||||
.filter((field) => field.name !== httpOptions.body &&
|
||||
!params.find(param => param === field.name))
|
||||
.map((field) => {
|
||||
return {
|
||||
name: field.name,
|
||||
in: "query",
|
||||
schema: Object.assign({}, genField(ctx, field))
|
||||
};
|
||||
});
|
||||
return [
|
||||
...queryString,
|
||||
...urlParams,
|
||||
];
|
||||
}
|
||||
/**
|
||||
* Generates OpenAPI Components
|
||||
* @param ctx
|
||||
* @param methods
|
||||
*/
|
||||
function genComponents(ctx, methods) {
|
||||
const components = {
|
||||
schemas: {}
|
||||
};
|
||||
methods.reduce((schemas, method) => {
|
||||
genSchema(ctx, schemas, method.inputType);
|
||||
genSchema(ctx, schemas, method.outputType);
|
||||
return schemas;
|
||||
}, components.schemas);
|
||||
return components;
|
||||
}
|
||||
/**
|
||||
* Generate OpenAPI Schemas
|
||||
* @param ctx
|
||||
* @param schemas
|
||||
* @param typeName
|
||||
*/
|
||||
function genSchema(ctx, schemas, typeName) {
|
||||
const registry = ctx.registry;
|
||||
const localName = localMessageName(ctx, typeName);
|
||||
if (!localName) {
|
||||
return;
|
||||
}
|
||||
const descriptor = registry.resolveTypeName(typeName);
|
||||
if (schemas[localName]) {
|
||||
return;
|
||||
}
|
||||
// Handle OneOf
|
||||
if (descriptor.field.some((field) => registry.isUserDeclaredOneof(field))) {
|
||||
schemas[localName] = genOneOfType(ctx, descriptor);
|
||||
descriptor.oneofDecl.forEach((oneOfField, index) => {
|
||||
const oneOfTyName = `${localName}_${capitalizeFirstLetter(oneOfField.name)}`;
|
||||
const oneOfFields = descriptor.field.filter(field => {
|
||||
return field.oneofIndex === index;
|
||||
});
|
||||
schemas[oneOfTyName] = genOneOfTypeKind(ctx, descriptor, oneOfFields);
|
||||
});
|
||||
}
|
||||
else {
|
||||
schemas[localName] = genType(ctx, descriptor);
|
||||
}
|
||||
descriptor.field.forEach((field) => {
|
||||
if (field.type !== plugin_framework_1.FieldDescriptorProto_Type.MESSAGE || !registry.isMapField(field)) {
|
||||
return;
|
||||
}
|
||||
if (registry.isMapField(field)) {
|
||||
const entry = registry.resolveTypeName(field.typeName);
|
||||
if (plugin_framework_1.DescriptorProto.is(entry)) {
|
||||
const valueField = entry.field.find(fd => fd.number === 2);
|
||||
if (!valueField) {
|
||||
return;
|
||||
}
|
||||
if (valueField.type !== plugin_framework_1.FieldDescriptorProto_Type.MESSAGE) {
|
||||
return;
|
||||
}
|
||||
field = valueField;
|
||||
}
|
||||
}
|
||||
else if (registry.isSyntheticElement(descriptor)) {
|
||||
return;
|
||||
}
|
||||
genSchema(ctx, schemas, field.typeName);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Generate an OpenAPI type
|
||||
* @param ctx
|
||||
* @param message
|
||||
*/
|
||||
function genType(ctx, message) {
|
||||
const description = genDescription(ctx, message);
|
||||
return {
|
||||
properties: genMessageProperties(ctx, message),
|
||||
description,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate a Protobuf to OpenAPI oneof type
|
||||
* @param ctx
|
||||
* @param message
|
||||
*/
|
||||
function genOneOfType(ctx, message) {
|
||||
const description = genDescription(ctx, message);
|
||||
const oneOf = {
|
||||
allOf: [
|
||||
{
|
||||
type: "object",
|
||||
properties: genMessageProperties(ctx, message),
|
||||
},
|
||||
],
|
||||
description,
|
||||
};
|
||||
message.oneofDecl.forEach((field) => {
|
||||
oneOf.allOf.push({
|
||||
$ref: `#/components/schemas/${message.name}_${capitalizeFirstLetter(field.name)}`
|
||||
});
|
||||
});
|
||||
return oneOf;
|
||||
}
|
||||
/**
|
||||
* Generate one of type
|
||||
* @param ctx
|
||||
* @param message
|
||||
* @param oneOfFields
|
||||
*/
|
||||
function genOneOfTypeKind(ctx, message, oneOfFields) {
|
||||
return {
|
||||
oneOf: oneOfFields.map((oneOf) => {
|
||||
return {
|
||||
type: "object",
|
||||
properties: {
|
||||
[oneOf.name]: genField(ctx, oneOf),
|
||||
}
|
||||
};
|
||||
})
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate message properties
|
||||
* @param ctx
|
||||
* @param message
|
||||
*/
|
||||
function genMessageProperties(ctx, message) {
|
||||
const registry = ctx.registry;
|
||||
return message.field.reduce((fields, field) => {
|
||||
if (registry.isUserDeclaredOneof(field)) {
|
||||
return fields;
|
||||
}
|
||||
fields[field.name] = genField(ctx, field);
|
||||
return fields;
|
||||
}, {});
|
||||
}
|
||||
/**
|
||||
* Generates OpenAPI $ref
|
||||
* @param ctx
|
||||
* @param name
|
||||
*/
|
||||
function genRef(ctx, name) {
|
||||
const messageType = localMessageName(ctx, name);
|
||||
return `#/components/schemas/${messageType}`;
|
||||
}
|
||||
/**
|
||||
* Generate field definition
|
||||
* @param ctx
|
||||
* @param field
|
||||
*/
|
||||
function genField(ctx, field) {
|
||||
let openApiType;
|
||||
const registry = ctx.registry;
|
||||
switch (field.type) {
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.DOUBLE:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.FLOAT:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.BOOL:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.STRING:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.FIXED32:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.FIXED64:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.INT32:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.INT64:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.SFIXED32:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.SFIXED64:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.SINT32:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.SINT64:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.UINT32:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.UINT64:
|
||||
openApiType = {
|
||||
type: genScalar(field.type),
|
||||
};
|
||||
break;
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.BYTES:
|
||||
openApiType = {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "integer",
|
||||
}
|
||||
};
|
||||
break;
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.ENUM:
|
||||
const enumType = registry.getEnumFieldEnum(field);
|
||||
openApiType = genEnum(enumType);
|
||||
break;
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.MESSAGE:
|
||||
// Map type
|
||||
if (registry.isMapField(field)) {
|
||||
const mapTypeValue = registry.getMapValueType(field);
|
||||
if (typeof mapTypeValue === "number") {
|
||||
const scalar = mapTypeValue;
|
||||
openApiType = {
|
||||
type: "object",
|
||||
additionalProperties: {
|
||||
type: genScalar(scalar)
|
||||
}
|
||||
};
|
||||
}
|
||||
else if (plugin_framework_1.EnumDescriptorProto.is(mapTypeValue)) {
|
||||
openApiType = {
|
||||
type: "object",
|
||||
additionalProperties: Object.assign({}, genEnum(mapTypeValue))
|
||||
};
|
||||
}
|
||||
else if (plugin_framework_1.DescriptorProto.is(mapTypeValue)) {
|
||||
openApiType = {
|
||||
type: "object",
|
||||
additionalProperties: {
|
||||
$ref: `#/components/schemas/${mapTypeValue.name}`,
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
throw new Error("map value not supported");
|
||||
}
|
||||
break;
|
||||
}
|
||||
openApiType = {
|
||||
$ref: genRef(ctx, field.typeName),
|
||||
};
|
||||
break;
|
||||
default:
|
||||
throw new Error(`${field.name} of type ${field.type} not supported`);
|
||||
}
|
||||
const description = genDescription(ctx, field);
|
||||
if (field.label === plugin_framework_1.FieldDescriptorProto_Label.REPEATED && !registry.isMapField(field)) {
|
||||
return {
|
||||
type: "array",
|
||||
items: openApiType,
|
||||
description: description || "",
|
||||
};
|
||||
}
|
||||
if (field.type !== plugin_framework_1.FieldDescriptorProto_Type.MESSAGE) {
|
||||
openApiType.description = description || "";
|
||||
}
|
||||
return openApiType;
|
||||
}
|
||||
/**
|
||||
* Generates enum definition
|
||||
* @param enumType
|
||||
*/
|
||||
function genEnum(enumType) {
|
||||
return {
|
||||
type: 'string',
|
||||
enum: enumType.value.map((value) => {
|
||||
return value.name;
|
||||
})
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Generate scalar
|
||||
* @param type
|
||||
*/
|
||||
function genScalar(type) {
|
||||
switch (type) {
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.BOOL:
|
||||
return "boolean";
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.DOUBLE:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.FLOAT:
|
||||
return "number";
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.STRING:
|
||||
return "string";
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.FIXED32:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.FIXED64:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.INT32:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.INT64:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.SFIXED32:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.SFIXED64:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.SINT32:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.SINT64:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.UINT32:
|
||||
case plugin_framework_1.FieldDescriptorProto_Type.UINT64:
|
||||
return "integer";
|
||||
default:
|
||||
throw new Error(`${type} is not a scalar value`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Generates the description
|
||||
* @param ctx
|
||||
* @param descriptor
|
||||
*/
|
||||
function genDescription(ctx, descriptor) {
|
||||
const registry = ctx.registry;
|
||||
const source = registry.sourceCodeComments(descriptor);
|
||||
const description = source.leading || source.trailing || "";
|
||||
return description.trim();
|
||||
}
|
||||
/**
|
||||
* Format protobuf name
|
||||
* @param ctx
|
||||
* @param name
|
||||
*/
|
||||
function localMessageName(ctx, name) {
|
||||
const registry = ctx.registry;
|
||||
const symbols = ctx.symbols;
|
||||
const entry = symbols.find(registry.resolveTypeName(name));
|
||||
if (!entry) {
|
||||
return "";
|
||||
}
|
||||
return local_type_name_1.createLocalTypeName(entry.descriptor, registry);
|
||||
}
|
||||
function parseUriParams(uri) {
|
||||
return getMatches(uri, /{([a-zA-Z_0-9]+)}/g, 1);
|
||||
}
|
||||
function getMatches(str, regex, index = 1) {
|
||||
const matches = [];
|
||||
let match;
|
||||
while (match = regex.exec(str)) {
|
||||
matches.push(match[index]);
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
function capitalizeFirstLetter(str) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
}
|
||||
20
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/twirp.d.ts
generated
vendored
Normal file
20
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/twirp.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { FileDescriptorProto } from "@protobuf-ts/plugin-framework";
|
||||
/**
|
||||
* Generates the client and server implementation of the twirp
|
||||
* specification.
|
||||
* @param ctx
|
||||
* @param file
|
||||
*/
|
||||
export declare function generateTwirp(ctx: any, file: FileDescriptorProto): Promise<string>;
|
||||
/**
|
||||
* Generates the client implementation of the twirp specification.
|
||||
* @param ctx
|
||||
* @param file
|
||||
*/
|
||||
export declare function generateTwirpClient(ctx: any, file: FileDescriptorProto): Promise<string>;
|
||||
/**
|
||||
* Generates the server implementation of the twirp specification.
|
||||
* @param ctx
|
||||
* @param file
|
||||
*/
|
||||
export declare function generateTwirpServer(ctx: any, file: FileDescriptorProto): Promise<string>;
|
||||
448
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/twirp.js
generated
vendored
Normal file
448
github/codeql-action-v2/node_modules/twirp-ts/build/protoc-gen-twirp-ts/gen/twirp.js
generated
vendored
Normal file
|
|
@ -0,0 +1,448 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
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) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.generateTwirpServer = exports.generateTwirpClient = exports.generateTwirp = void 0;
|
||||
const ts_poet_1 = require("ts-poet");
|
||||
const camel_case_1 = require("camel-case");
|
||||
const local_type_name_1 = require("../local-type-name");
|
||||
const path_1 = __importDefault(require("path"));
|
||||
const TwirpServer = ts_poet_1.imp("TwirpServer@twirp-ts");
|
||||
const Interceptor = ts_poet_1.imp("Interceptor@twirp-ts");
|
||||
const RouterEvents = ts_poet_1.imp("RouterEvents@twirp-ts");
|
||||
const chainInterceptors = ts_poet_1.imp("chainInterceptors@twirp-ts");
|
||||
const TwirpContentType = ts_poet_1.imp("TwirpContentType@twirp-ts");
|
||||
const TwirpContext = ts_poet_1.imp("TwirpContext@twirp-ts");
|
||||
const TwirpError = ts_poet_1.imp("TwirpError@twirp-ts");
|
||||
const TwirpErrorCode = ts_poet_1.imp("TwirpErrorCode@twirp-ts");
|
||||
/**
|
||||
* Generates the client and server implementation of the twirp
|
||||
* specification.
|
||||
* @param ctx
|
||||
* @param file
|
||||
*/
|
||||
function generateTwirp(ctx, file) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const contents = file.service.map((service) => {
|
||||
return ts_poet_1.joinCode([
|
||||
genClient(ctx, file, service),
|
||||
genServer(ctx, file, service),
|
||||
], { on: "\n\n" });
|
||||
});
|
||||
return ts_poet_1.joinCode(contents, { on: "\n\n" }).toStringWithImports();
|
||||
});
|
||||
}
|
||||
exports.generateTwirp = generateTwirp;
|
||||
/**
|
||||
* Generates the client implementation of the twirp specification.
|
||||
* @param ctx
|
||||
* @param file
|
||||
*/
|
||||
function generateTwirpClient(ctx, file) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const contents = file.service.map((service) => {
|
||||
return ts_poet_1.joinCode([genClient(ctx, file, service)], { on: "\n\n" });
|
||||
});
|
||||
return ts_poet_1.joinCode(contents, { on: "\n\n" }).toStringWithImports();
|
||||
});
|
||||
}
|
||||
exports.generateTwirpClient = generateTwirpClient;
|
||||
/**
|
||||
* Generates the server implementation of the twirp specification.
|
||||
* @param ctx
|
||||
* @param file
|
||||
*/
|
||||
function generateTwirpServer(ctx, file) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const contents = file.service.map((service) => {
|
||||
return ts_poet_1.joinCode([genServer(ctx, file, service)], { on: "\n\n" });
|
||||
});
|
||||
return ts_poet_1.joinCode(contents, { on: "\n\n" }).toStringWithImports();
|
||||
});
|
||||
}
|
||||
exports.generateTwirpServer = generateTwirpServer;
|
||||
function genClient(ctx, file, service) {
|
||||
return ts_poet_1.code `
|
||||
//==================================//
|
||||
// Client Code //
|
||||
//==================================//
|
||||
|
||||
interface Rpc {
|
||||
request(
|
||||
service: string,
|
||||
method: string,
|
||||
contentType: "application/json" | "application/protobuf",
|
||||
data: object | Uint8Array,
|
||||
): Promise<object | Uint8Array>;
|
||||
}
|
||||
|
||||
${genTwirpClientInterface(ctx, file, service)}
|
||||
|
||||
${genTwripClientJSONImpl(ctx, file, service)}
|
||||
${genTwripClientProtobufImpl(ctx, file, service)}
|
||||
`;
|
||||
}
|
||||
function genTwirpClientInterface(ctx, file, service) {
|
||||
const methods = service.method.map((method) => {
|
||||
return ts_poet_1.code `
|
||||
${formatMethodName(ctx, method.name)}(request: ${relativeMessageName(ctx, file, method.inputType)}): Promise<${relativeMessageName(ctx, file, method.outputType)}>
|
||||
`;
|
||||
});
|
||||
return ts_poet_1.code `
|
||||
export interface ${service.name}Client {
|
||||
${ts_poet_1.joinCode(methods, { on: "\n" })}
|
||||
}
|
||||
`;
|
||||
}
|
||||
/**
|
||||
* Generates the json client
|
||||
* @param ctx
|
||||
* @param file
|
||||
* @param service
|
||||
*/
|
||||
function genTwripClientJSONImpl(ctx, file, service) {
|
||||
const methods = service.method.map((method) => {
|
||||
return ts_poet_1.code `
|
||||
${formatMethodName(ctx, method.name)}(request: ${relativeMessageName(ctx, file, method.inputType)}): Promise<${relativeMessageName(ctx, file, method.outputType)}> {
|
||||
const data = ${relativeMessageName(ctx, file, method.inputType)}.${encodeJSON(ctx, "request")};
|
||||
const promise = this.rpc.request(
|
||||
"${file.package ? file.package + "." : ""}${service.name}",
|
||||
"${formatMethodName(ctx, method.name)}",
|
||||
"application/json",
|
||||
data as object,
|
||||
);
|
||||
return promise.then((data) => ${relativeMessageName(ctx, file, method.outputType)}.${decodeJSON(ctx, "data as any")});
|
||||
}
|
||||
`;
|
||||
});
|
||||
const bindings = service.method.map((method) => {
|
||||
return ts_poet_1.code `
|
||||
this.${formatMethodName(ctx, method.name)}.bind(this);
|
||||
`;
|
||||
});
|
||||
return ts_poet_1.code `
|
||||
export class ${service.name}ClientJSON implements ${service.name}Client {
|
||||
private readonly rpc: Rpc;
|
||||
constructor(rpc: Rpc) {
|
||||
this.rpc = rpc;
|
||||
${ts_poet_1.joinCode(bindings, { on: `\n` })}
|
||||
}
|
||||
${ts_poet_1.joinCode(methods, { on: `\n\n` })}
|
||||
}
|
||||
`;
|
||||
}
|
||||
/**
|
||||
* Generate the protobuf client
|
||||
* @param ctx
|
||||
* @param file
|
||||
* @param service
|
||||
*/
|
||||
function genTwripClientProtobufImpl(ctx, file, service) {
|
||||
const methods = service.method.map((method) => {
|
||||
return ts_poet_1.code `
|
||||
${formatMethodName(ctx, method.name)}(request: ${relativeMessageName(ctx, file, method.inputType)}): Promise<${relativeMessageName(ctx, file, method.outputType)}> {
|
||||
const data = ${relativeMessageName(ctx, file, method.inputType)}.${encodeProtobuf(ctx, "request")};
|
||||
const promise = this.rpc.request(
|
||||
"${file.package ? file.package + "." : ""}${service.name}",
|
||||
"${formatMethodName(ctx, method.name)}",
|
||||
"application/protobuf",
|
||||
data,
|
||||
);
|
||||
return promise.then((data) => ${relativeMessageName(ctx, file, method.outputType)}.${decodeProtobuf(ctx, "data as Uint8Array")});
|
||||
}
|
||||
`;
|
||||
});
|
||||
const bindings = service.method.map((method) => {
|
||||
return ts_poet_1.code `
|
||||
this.${formatMethodName(ctx, method.name)}.bind(this);
|
||||
`;
|
||||
});
|
||||
return ts_poet_1.code `
|
||||
export class ${service.name}ClientProtobuf implements ${service.name}Client {
|
||||
private readonly rpc: Rpc;
|
||||
constructor(rpc: Rpc) {
|
||||
this.rpc = rpc;
|
||||
${ts_poet_1.joinCode(bindings, { on: `\n` })}
|
||||
}
|
||||
${ts_poet_1.joinCode(methods, { on: `\n\n` })}
|
||||
}
|
||||
`;
|
||||
}
|
||||
/**
|
||||
* Generates twirp service definition
|
||||
* @param ctx
|
||||
* @param file
|
||||
* @param service
|
||||
*/
|
||||
function genTwirpService(ctx, file, service) {
|
||||
const importService = service.name;
|
||||
const serverMethods = service.method.map((method) => {
|
||||
return ts_poet_1.code `
|
||||
${formatMethodName(ctx, method.name)}(ctx: T, request: ${relativeMessageName(ctx, file, method.inputType)}): Promise<${relativeMessageName(ctx, file, method.outputType)}>
|
||||
`;
|
||||
});
|
||||
const methodEnum = service.method.map((method) => {
|
||||
return ts_poet_1.code `${formatMethodName(ctx, method.name)} = "${formatMethodName(ctx, method.name)}",`;
|
||||
});
|
||||
const methodList = service.method.map((method) => {
|
||||
return ts_poet_1.code `${importService}Method.${formatMethodName(ctx, method.name)}`;
|
||||
});
|
||||
return ts_poet_1.code `
|
||||
export interface ${importService}Twirp<T extends ${TwirpContext} = ${TwirpContext}> {
|
||||
${ts_poet_1.joinCode(serverMethods, { on: `\n` })}
|
||||
}
|
||||
|
||||
export enum ${importService}Method {
|
||||
${ts_poet_1.joinCode(methodEnum, { on: "\n" })}
|
||||
}
|
||||
|
||||
export const ${importService}MethodList = [${ts_poet_1.joinCode(methodList, { on: "," })}];
|
||||
`;
|
||||
}
|
||||
/**
|
||||
* Generates the twirp server specification
|
||||
* @param ctx
|
||||
* @param file
|
||||
* @param service
|
||||
*/
|
||||
function genServer(ctx, file, service) {
|
||||
var _a;
|
||||
const importService = service.name;
|
||||
return ts_poet_1.code `
|
||||
|
||||
//==================================//
|
||||
// Server Code //
|
||||
//==================================//
|
||||
|
||||
${genTwirpService(ctx, file, service)}
|
||||
|
||||
export function create${importService}Server<T extends ${TwirpContext} = ${TwirpContext}>(service: ${importService}Twirp<T>) {
|
||||
return new ${TwirpServer}<${importService}Twirp, T>({
|
||||
service,
|
||||
packageName: "${(_a = file.package) !== null && _a !== void 0 ? _a : ''}",
|
||||
serviceName: "${importService}",
|
||||
methodList: ${importService}MethodList,
|
||||
matchRoute: match${importService}Route,
|
||||
})
|
||||
}
|
||||
${genRouteHandler(ctx, file, service)}
|
||||
${ts_poet_1.joinCode(genHandleRequestMethod(ctx, file, service), { on: "\n\n" })}
|
||||
${ts_poet_1.joinCode(genHandleJSONRequest(ctx, file, service), { on: "\n\n" })}
|
||||
${ts_poet_1.joinCode(genHandleProtobufRequest(ctx, file, service), { on: "\n\n" })}
|
||||
`;
|
||||
}
|
||||
/**
|
||||
* Generate the route handler
|
||||
* @param ctx
|
||||
* @param file
|
||||
* @param service
|
||||
*/
|
||||
function genRouteHandler(ctx, file, service) {
|
||||
const cases = service.method.map(method => ts_poet_1.code `
|
||||
case "${formatMethodName(ctx, method.name)}":
|
||||
return async (ctx: T, service: ${service.name}Twirp ,data: Buffer, interceptors?: ${Interceptor}<T, ${relativeMessageName(ctx, file, method.inputType)}, ${relativeMessageName(ctx, file, method.outputType)}>[]) => {
|
||||
ctx = {...ctx, methodName: "${formatMethodName(ctx, method.name)}" }
|
||||
await events.onMatch(ctx);
|
||||
return handle${formatMethodName(ctx, method.name, service.name)}Request(ctx, service, data, interceptors)
|
||||
}
|
||||
`);
|
||||
return ts_poet_1.code `
|
||||
function match${service.name}Route<T extends ${TwirpContext} = ${TwirpContext}>(method: string, events: ${RouterEvents}<T>) {
|
||||
switch(method) {
|
||||
${ts_poet_1.joinCode(cases, { on: `\n` })}
|
||||
default:
|
||||
events.onNotFound();
|
||||
const msg = \`no handler found\`;
|
||||
throw new ${TwirpError}(${TwirpErrorCode}.BadRoute, msg)
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
/**
|
||||
* Generate request handler for methods
|
||||
* @param ctx
|
||||
* @param file
|
||||
* @param service
|
||||
*/
|
||||
function genHandleRequestMethod(ctx, file, service) {
|
||||
return service.method.map(method => {
|
||||
return ts_poet_1.code `
|
||||
function handle${formatMethodName(ctx, method.name, service.name)}Request<T extends ${TwirpContext} = ${TwirpContext}>(ctx: T, service: ${service.name}Twirp ,data: Buffer, interceptors?: ${Interceptor}<T, ${relativeMessageName(ctx, file, method.inputType)}, ${relativeMessageName(ctx, file, method.outputType)}>[]): Promise<string | Uint8Array> {
|
||||
switch (ctx.contentType) {
|
||||
case ${TwirpContentType}.JSON:
|
||||
return handle${formatMethodName(ctx, method.name, service.name)}JSON<T>(ctx, service, data, interceptors);
|
||||
case ${TwirpContentType}.Protobuf:
|
||||
return handle${formatMethodName(ctx, method.name, service.name)}Protobuf<T>(ctx, service, data, interceptors);
|
||||
default:
|
||||
const msg = "unexpected Content-Type";
|
||||
throw new ${TwirpError}(${TwirpErrorCode}.BadRoute, msg);
|
||||
}
|
||||
}
|
||||
`;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Generate a JSON request handler for a method
|
||||
* @param ctx
|
||||
* @param file
|
||||
* @param service
|
||||
*/
|
||||
function genHandleJSONRequest(ctx, file, service) {
|
||||
return service.method.map(method => {
|
||||
return ts_poet_1.code `
|
||||
|
||||
async function handle${formatMethodName(ctx, method.name, service.name)}JSON<T extends ${TwirpContext} = ${TwirpContext}>(ctx: T, service: ${service.name}Twirp, data: Buffer, interceptors?: ${Interceptor}<T, ${relativeMessageName(ctx, file, method.inputType)}, ${relativeMessageName(ctx, file, method.outputType)}>[]) {
|
||||
let request: ${relativeMessageName(ctx, file, method.inputType)}
|
||||
let response: ${relativeMessageName(ctx, file, method.outputType)}
|
||||
|
||||
try {
|
||||
const body = JSON.parse(data.toString() || "{}");
|
||||
request = ${relativeMessageName(ctx, file, method.inputType)}.${decodeJSON(ctx, "body")};
|
||||
} catch(e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the json request could not be decoded";
|
||||
throw new ${TwirpError}(${TwirpErrorCode}.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = ${chainInterceptors}(...interceptors) as Interceptor<T, ${relativeMessageName(ctx, file, method.inputType)}, ${relativeMessageName(ctx, file, method.outputType)}>
|
||||
response = await interceptor(ctx, request!, (ctx, inputReq) => {
|
||||
return service.${formatMethodName(ctx, method.name)}(ctx, inputReq);
|
||||
});
|
||||
} else {
|
||||
response = await service.${formatMethodName(ctx, method.name)}(ctx, request!)
|
||||
}
|
||||
|
||||
return JSON.stringify(${relativeMessageName(ctx, file, method.outputType)}.${encodeJSON(ctx, "response")} as string);
|
||||
}
|
||||
`;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Generates a protobuf request handler
|
||||
* @param ctx
|
||||
* @param file
|
||||
* @param service
|
||||
*/
|
||||
function genHandleProtobufRequest(ctx, file, service) {
|
||||
return service.method.map(method => {
|
||||
return ts_poet_1.code `
|
||||
|
||||
async function handle${formatMethodName(ctx, method.name, service.name)}Protobuf<T extends ${TwirpContext} = ${TwirpContext}>(ctx: T, service: ${service.name}Twirp, data: Buffer, interceptors?: ${Interceptor}<T, ${relativeMessageName(ctx, file, method.inputType)}, ${relativeMessageName(ctx, file, method.outputType)}>[]) {
|
||||
let request: ${relativeMessageName(ctx, file, method.inputType)}
|
||||
let response: ${relativeMessageName(ctx, file, method.outputType)}
|
||||
|
||||
try {
|
||||
request = ${relativeMessageName(ctx, file, method.inputType)}.${decodeProtobuf(ctx, "data")};
|
||||
} catch(e) {
|
||||
if (e instanceof Error) {
|
||||
const msg = "the protobuf request could not be decoded";
|
||||
throw new ${TwirpError}(${TwirpErrorCode}.Malformed, msg).withCause(e, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (interceptors && interceptors.length > 0) {
|
||||
const interceptor = ${chainInterceptors}(...interceptors) as Interceptor<T, ${relativeMessageName(ctx, file, method.inputType)}, ${relativeMessageName(ctx, file, method.outputType)}>
|
||||
response = await interceptor(ctx, request!, (ctx, inputReq) => {
|
||||
return service.${formatMethodName(ctx, method.name)}(ctx, inputReq);
|
||||
});
|
||||
} else {
|
||||
response = await service.${formatMethodName(ctx, method.name)}(ctx, request!)
|
||||
}
|
||||
|
||||
return Buffer.from(${relativeMessageName(ctx, file, method.outputType)}.${encodeProtobuf(ctx, "response")});
|
||||
}
|
||||
`;
|
||||
});
|
||||
}
|
||||
var SupportedLibs;
|
||||
(function (SupportedLibs) {
|
||||
SupportedLibs["TSProto"] = "ts-proto";
|
||||
SupportedLibs["ProtobufTS"] = "protobuf-ts";
|
||||
})(SupportedLibs || (SupportedLibs = {}));
|
||||
function validateLib(lib) {
|
||||
switch (lib) {
|
||||
case "ts-proto":
|
||||
return SupportedLibs.TSProto;
|
||||
case "protobuf-ts":
|
||||
return SupportedLibs.ProtobufTS;
|
||||
default:
|
||||
throw new Error(`library ${lib} not supported`);
|
||||
}
|
||||
}
|
||||
function decodeJSON(ctx, dataName) {
|
||||
const protoLib = validateLib(ctx.lib);
|
||||
if (protoLib === SupportedLibs.TSProto) {
|
||||
return ts_poet_1.code `fromJSON(${dataName})`;
|
||||
}
|
||||
return ts_poet_1.code `fromJson(${dataName}, { ignoreUnknownFields: true })`;
|
||||
}
|
||||
function encodeJSON(ctx, dataName) {
|
||||
const protoLib = validateLib(ctx.lib);
|
||||
if (protoLib === SupportedLibs.TSProto) {
|
||||
return ts_poet_1.code `toJSON(${dataName})`;
|
||||
}
|
||||
return ts_poet_1.code `toJson(${dataName}, {useProtoFieldName: true, emitDefaultValues: ${ctx.emitDefaultValues ? 'true' : 'false'}})`;
|
||||
}
|
||||
function encodeProtobuf(ctx, dataName) {
|
||||
const protoLib = validateLib(ctx.lib);
|
||||
if (protoLib === SupportedLibs.TSProto) {
|
||||
return ts_poet_1.code `encode(${dataName}).finish()`;
|
||||
}
|
||||
return ts_poet_1.code `toBinary(${dataName})`;
|
||||
}
|
||||
function decodeProtobuf(ctx, dataName) {
|
||||
const protoLib = validateLib(ctx.lib);
|
||||
if (protoLib === SupportedLibs.TSProto) {
|
||||
return ts_poet_1.code `decode(${dataName})`;
|
||||
}
|
||||
return ts_poet_1.code `fromBinary(${dataName})`;
|
||||
}
|
||||
function relativeMessageName(ctx, file, messageName) {
|
||||
const registry = ctx.registry;
|
||||
const symbols = ctx.symbols;
|
||||
const entry = symbols.find(registry.resolveTypeName(messageName));
|
||||
if (!entry) {
|
||||
throw new Error(`Message ${messageName} not found`);
|
||||
}
|
||||
const messageType = local_type_name_1.createLocalTypeName(entry.descriptor, registry);
|
||||
const relativePath = createRelativeImportPath(file.name, entry.file.getFilename());
|
||||
return ts_poet_1.code `${ts_poet_1.imp(`${messageType}@${relativePath}`)}`;
|
||||
}
|
||||
/**
|
||||
* Create a relative path for an import statement like
|
||||
* `import {Foo} from "./foo"`
|
||||
*/
|
||||
function createRelativeImportPath(currentPath, pathToImportFrom) {
|
||||
// create relative path to the file to import
|
||||
let fromPath = path_1.default.relative(path_1.default.dirname(currentPath), pathToImportFrom);
|
||||
// on windows, this may add backslash directory separators.
|
||||
// we replace them with forward slash.
|
||||
if (path_1.default.sep !== "/") {
|
||||
fromPath = fromPath.split(path_1.default.sep).join("/");
|
||||
}
|
||||
// drop file extension
|
||||
fromPath = fromPath.replace(/\.[a-z]+$/, '');
|
||||
// make sure to start with './' to signal relative path to module resolution
|
||||
if (!fromPath.startsWith('../') && !fromPath.startsWith('./')) {
|
||||
fromPath = './' + fromPath;
|
||||
}
|
||||
return fromPath;
|
||||
}
|
||||
function formatMethodName(ctx, methodName, serviceName) {
|
||||
if (methodName === undefined)
|
||||
return undefined;
|
||||
serviceName = serviceName || "";
|
||||
return ctx.camelCase ? camel_case_1.camelCase(serviceName) + camel_case_1.camelCase(methodName) : serviceName + methodName;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue