@webda/grpc 4.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.webda/cache +4 -0
- package/CHANGELOG.md +54 -0
- package/LICENSE +166 -0
- package/README.md +100 -0
- package/lib/grpc-stream.d.ts +109 -0
- package/lib/grpc-stream.d.ts.map +1 -0
- package/lib/grpc-stream.js +162 -0
- package/lib/grpc-stream.js.map +1 -0
- package/lib/grpcservice.service.d.ts +112 -0
- package/lib/grpcservice.service.d.ts.map +1 -0
- package/lib/grpcservice.service.js +459 -0
- package/lib/grpcservice.service.js.map +1 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +4 -0
- package/lib/index.js.map +1 -0
- package/lib/proto-generator.d.ts +14 -0
- package/lib/proto-generator.d.ts.map +1 -0
- package/lib/proto-generator.js +312 -0
- package/lib/proto-generator.js.map +1 -0
- package/package.json +42 -0
- package/src/build-integration.spec.ts +187 -0
- package/src/grpc-stream.spec.ts +417 -0
- package/src/grpc-stream.ts +192 -0
- package/src/grpcservice.service.ts +462 -0
- package/src/grpcservice.spec.ts +1092 -0
- package/src/index.ts +4 -0
- package/src/proto-generator.spec.ts +696 -0
- package/src/proto-generator.ts +338 -0
- package/tsconfig.json +33 -0
- package/vitest.config.ts +20 -0
- package/webda.module.json +111 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import type { OperationDefinition } from "@webda/core";
|
|
2
|
+
import type { JSONSchema7 } from "json-schema";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generate a .proto file from registered operations and their schemas.
|
|
6
|
+
*
|
|
7
|
+
* Groups operations by prefix (e.g., "Post.Create" → service PostService)
|
|
8
|
+
* and converts JSON Schema input/output types to protobuf messages.
|
|
9
|
+
* @param operations - map of operation IDs to their definitions
|
|
10
|
+
* @param schemas - all known JSON schemas keyed by schema reference name
|
|
11
|
+
* @param packageName - protobuf package name to use in the generated file
|
|
12
|
+
* @returns the complete .proto file content as a string
|
|
13
|
+
*/
|
|
14
|
+
export function generateProto(
|
|
15
|
+
operations: Record<string, Omit<OperationDefinition, "service" | "method">>,
|
|
16
|
+
schemas: Record<string, JSONSchema7>,
|
|
17
|
+
packageName: string = "webda"
|
|
18
|
+
): string {
|
|
19
|
+
const lines: string[] = [];
|
|
20
|
+
const messages = new Map<string, string>(); // messageName → proto definition
|
|
21
|
+
const fieldCounter = 0;
|
|
22
|
+
|
|
23
|
+
lines.push('syntax = "proto3";');
|
|
24
|
+
lines.push("");
|
|
25
|
+
lines.push(`package ${packageName};`);
|
|
26
|
+
lines.push("");
|
|
27
|
+
lines.push('import "google/protobuf/empty.proto";');
|
|
28
|
+
lines.push('import "google/protobuf/struct.proto";');
|
|
29
|
+
lines.push("");
|
|
30
|
+
|
|
31
|
+
// Group operations by service prefix
|
|
32
|
+
const serviceGroups = new Map<string, { opId: string; op: any; rpcName: string }[]>();
|
|
33
|
+
for (const [opId, op] of Object.entries(operations)) {
|
|
34
|
+
if (op.hidden) continue;
|
|
35
|
+
const dotIdx = opId.indexOf(".");
|
|
36
|
+
const prefix = dotIdx > 0 ? opId.substring(0, dotIdx) : "Default";
|
|
37
|
+
// proto3 RPC method names must match `[A-Za-z_][A-Za-z0-9_]*` — dots are
|
|
38
|
+
// namespace separators and rejected by the parser. Behavior operations
|
|
39
|
+
// are namespaced as `<Model>.<Attribute>.<Action>` (e.g.
|
|
40
|
+
// `Post.MainImage.Delete`), so the trailing portion still carries a
|
|
41
|
+
// dot. Flatten to underscore so the parser accepts the rpc name.
|
|
42
|
+
const rpcName = (dotIdx > 0 ? opId.substring(dotIdx + 1) : opId).replace(/\./g, "_");
|
|
43
|
+
if (!serviceGroups.has(prefix)) {
|
|
44
|
+
serviceGroups.set(prefix, []);
|
|
45
|
+
}
|
|
46
|
+
serviceGroups.get(prefix)!.push({ opId, op, rpcName });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Webda operation inputs ending in `?` are the "ignoreRequired" variant of
|
|
50
|
+
// the base schema; strip the suffix when looking the schema up since only
|
|
51
|
+
// the base key exists in the registry.
|
|
52
|
+
const resolveSchemaRef = (ref?: string): string | undefined => {
|
|
53
|
+
if (!ref || ref === "void") return undefined;
|
|
54
|
+
if (schemas[ref]) return ref;
|
|
55
|
+
if (ref.endsWith("?") && schemas[ref.slice(0, -1)]) return ref.slice(0, -1);
|
|
56
|
+
return undefined;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Hoist every operation schema's local `definitions` block into the flat
|
|
60
|
+
// schema registry so $refs like `#/definitions/BinaryMap<T>` (which the
|
|
61
|
+
// schema generator emits next to its hoisted definitions block) resolve
|
|
62
|
+
// to a real shape instead of falling back to `google.protobuf.Struct`.
|
|
63
|
+
// The compiler's `normalizeSchemaDefinitions` already lifted these to the
|
|
64
|
+
// schema root; we just need to fold them into the flat registry the proto
|
|
65
|
+
// walker consults.
|
|
66
|
+
const enrichedSchemas: Record<string, JSONSchema7> = { ...schemas };
|
|
67
|
+
for (const op of Object.values(operations)) {
|
|
68
|
+
if (op.hidden) continue;
|
|
69
|
+
for (const ref of [op.input, op.output]) {
|
|
70
|
+
if (!ref || ref === "void") continue;
|
|
71
|
+
const baseRef = ref.endsWith("?") ? ref.slice(0, -1) : ref;
|
|
72
|
+
const target = enrichedSchemas[baseRef];
|
|
73
|
+
const localDefs = (target as any)?.definitions;
|
|
74
|
+
if (!localDefs) continue;
|
|
75
|
+
for (const [k, v] of Object.entries(localDefs)) {
|
|
76
|
+
if (!(k in enrichedSchemas)) {
|
|
77
|
+
enrichedSchemas[k] = v as JSONSchema7;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Generate messages for all referenced schemas
|
|
84
|
+
for (const [opId, op] of Object.entries(operations)) {
|
|
85
|
+
if (op.hidden) continue;
|
|
86
|
+
const inputRef = resolveSchemaRef(op.input);
|
|
87
|
+
if (inputRef) {
|
|
88
|
+
const msgName = schemaToMessageName(inputRef);
|
|
89
|
+
if (!messages.has(msgName)) {
|
|
90
|
+
messages.set(msgName, jsonSchemaToMessage(msgName, enrichedSchemas[inputRef], enrichedSchemas, messages));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const outputRef = resolveSchemaRef(op.output);
|
|
94
|
+
if (outputRef) {
|
|
95
|
+
const msgName = schemaToMessageName(outputRef);
|
|
96
|
+
if (!messages.has(msgName)) {
|
|
97
|
+
messages.set(msgName, jsonSchemaToMessage(msgName, enrichedSchemas[outputRef], enrichedSchemas, messages));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Write all messages
|
|
103
|
+
for (const [, msgDef] of messages) {
|
|
104
|
+
lines.push(msgDef);
|
|
105
|
+
lines.push("");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Write services
|
|
109
|
+
for (const [prefix, ops] of serviceGroups) {
|
|
110
|
+
lines.push(`service ${prefix}Service {`);
|
|
111
|
+
for (const { opId, op, rpcName } of ops) {
|
|
112
|
+
const inputType = getInputType(op, schemas, messages);
|
|
113
|
+
const outputType = getOutputType(op, schemas, messages);
|
|
114
|
+
const streaming = op.grpc?.streaming || "none";
|
|
115
|
+
|
|
116
|
+
const inputMod = streaming === "client" || streaming === "bidi" ? "stream " : "";
|
|
117
|
+
const outputMod = streaming === "server" || streaming === "bidi" ? "stream " : "";
|
|
118
|
+
|
|
119
|
+
if (op.summary) {
|
|
120
|
+
lines.push(` // ${op.summary}`);
|
|
121
|
+
}
|
|
122
|
+
lines.push(` rpc ${rpcName}(${inputMod}${inputType}) returns (${outputMod}${outputType});`);
|
|
123
|
+
}
|
|
124
|
+
lines.push("}");
|
|
125
|
+
lines.push("");
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return lines.join("\n");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Convert a schema reference name to a protobuf message name.
|
|
133
|
+
* "WebdaSample/Post" → "Post", "uuidRequest" → "UuidRequest"
|
|
134
|
+
* @param schemaRef - the schema reference string, e.g. "MyApp/Post" or "uuidRequest"
|
|
135
|
+
* @returns the PascalCase protobuf message name derived from the reference
|
|
136
|
+
*/
|
|
137
|
+
function schemaToMessageName(schemaRef: string): string {
|
|
138
|
+
// JSON-Pointer escapes (`%3C%7B%7D%3E`) survive into `$ref` strings when the
|
|
139
|
+
// schema generator names a definition like `BinaryFileInfo<{}>`. Decode
|
|
140
|
+
// them first so we can strip the generic-bracket noise rather than emitting
|
|
141
|
+
// `BinaryFileInfo%3C%7B%7D%3E` as a proto identifier (which the parser
|
|
142
|
+
// rejects as an illegal token).
|
|
143
|
+
let decoded: string;
|
|
144
|
+
try {
|
|
145
|
+
decoded = decodeURIComponent(schemaRef);
|
|
146
|
+
} catch {
|
|
147
|
+
decoded = schemaRef;
|
|
148
|
+
}
|
|
149
|
+
const tail = (decoded.includes("/") ? decoded.split("/").pop() : decoded) ?? decoded;
|
|
150
|
+
// Drop generic args (`<...>`) entirely — proto3 has no generic concept and
|
|
151
|
+
// the unresolved `T` made the generated schema collapse them to `<{}>`.
|
|
152
|
+
const stripped = tail.replace(/<[^>]*>/g, "");
|
|
153
|
+
// Sanitize anything left that proto3 doesn't accept in an identifier.
|
|
154
|
+
// proto3 idents match `[A-Za-z_][A-Za-z0-9_]*`; splitting on every other
|
|
155
|
+
// char and PascalCasing keeps the original word boundaries readable.
|
|
156
|
+
const cleaned = stripped
|
|
157
|
+
.split(/[^A-Za-z0-9]+/)
|
|
158
|
+
.filter(Boolean)
|
|
159
|
+
.map(s => s.charAt(0).toUpperCase() + s.slice(1))
|
|
160
|
+
.join("") || "Empty";
|
|
161
|
+
// proto3 identifiers must start with a letter or underscore; underscore
|
|
162
|
+
// prefix the cleaned name when it begins with a digit (e.g. `1Metadata`
|
|
163
|
+
// from a `&1$metadata` schema-generator artefact for unbound generics).
|
|
164
|
+
return /^[A-Za-z_]/.test(cleaned) ? cleaned : `_${cleaned}`;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get the protobuf input type for an operation.
|
|
169
|
+
* Merges parameters + input into a single request message if both exist.
|
|
170
|
+
* @param op - the operation definition containing optional input and parameters schema references
|
|
171
|
+
* @param schemas - all known JSON schemas keyed by schema reference name
|
|
172
|
+
* @param messages - accumulator map of already-generated protobuf message definitions
|
|
173
|
+
* @returns the protobuf type name to use as the RPC input type
|
|
174
|
+
*/
|
|
175
|
+
function getInputType(
|
|
176
|
+
op: any,
|
|
177
|
+
schemas: Record<string, JSONSchema7>,
|
|
178
|
+
messages: Map<string, string>
|
|
179
|
+
): string {
|
|
180
|
+
const ref = op.input && op.input !== "void"
|
|
181
|
+
? (schemas[op.input]
|
|
182
|
+
? op.input
|
|
183
|
+
: op.input.endsWith("?") && schemas[op.input.slice(0, -1)]
|
|
184
|
+
? op.input.slice(0, -1)
|
|
185
|
+
: undefined)
|
|
186
|
+
: undefined;
|
|
187
|
+
if (ref) {
|
|
188
|
+
return schemaToMessageName(ref);
|
|
189
|
+
}
|
|
190
|
+
return "google.protobuf.Empty";
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Get the protobuf output type for an operation.
|
|
195
|
+
* @param op - the operation definition containing an optional output schema reference
|
|
196
|
+
* @param schemas - all known JSON schemas keyed by schema reference name
|
|
197
|
+
* @param messages - accumulator map of already-generated protobuf message definitions
|
|
198
|
+
* @returns the protobuf type name to use as the RPC output type
|
|
199
|
+
*/
|
|
200
|
+
function getOutputType(
|
|
201
|
+
op: any,
|
|
202
|
+
schemas: Record<string, JSONSchema7>,
|
|
203
|
+
messages: Map<string, string>
|
|
204
|
+
): string {
|
|
205
|
+
if (op.output && op.output !== "void" && schemas[op.output]) {
|
|
206
|
+
return schemaToMessageName(op.output);
|
|
207
|
+
}
|
|
208
|
+
return "google.protobuf.Empty";
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Convert a JSON Schema object to a protobuf message definition.
|
|
213
|
+
* @param name - the protobuf message name to assign to this definition
|
|
214
|
+
* @param schema - the JSON Schema object describing the message fields
|
|
215
|
+
* @param allSchemas - all known JSON schemas, used to resolve nested references
|
|
216
|
+
* @param messages - accumulator map updated with any nested message definitions generated
|
|
217
|
+
* @returns the protobuf message block as a string
|
|
218
|
+
*/
|
|
219
|
+
function jsonSchemaToMessage(
|
|
220
|
+
name: string,
|
|
221
|
+
schema: JSONSchema7,
|
|
222
|
+
allSchemas: Record<string, JSONSchema7>,
|
|
223
|
+
messages: Map<string, string>
|
|
224
|
+
): string {
|
|
225
|
+
const lines: string[] = [];
|
|
226
|
+
lines.push(`message ${name} {`);
|
|
227
|
+
|
|
228
|
+
if (schema.properties) {
|
|
229
|
+
// JSON-Schema `required` list drives proto3 `optional` marker so that
|
|
230
|
+
// fields the caller didn't set aren't sent as empty-string defaults and
|
|
231
|
+
// trip pattern/format/minLength validations server-side.
|
|
232
|
+
const required = new Set((schema.required as string[]) || []);
|
|
233
|
+
let fieldNum = 1;
|
|
234
|
+
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
235
|
+
const prop = propSchema as JSONSchema7;
|
|
236
|
+
const protoType = jsonTypeToProto(propName, prop, name, allSchemas, messages);
|
|
237
|
+
const fieldType = prop.type === "array" ? jsonTypeToProto(propName, (prop.items as JSONSchema7) || {}, name, allSchemas, messages) : protoType;
|
|
238
|
+
if (prop.type === "array") {
|
|
239
|
+
lines.push(` repeated ${fieldType} ${propName} = ${fieldNum};`);
|
|
240
|
+
} else if (required.has(propName)) {
|
|
241
|
+
lines.push(` ${protoType} ${propName} = ${fieldNum};`);
|
|
242
|
+
} else {
|
|
243
|
+
lines.push(` optional ${protoType} ${propName} = ${fieldNum};`);
|
|
244
|
+
}
|
|
245
|
+
fieldNum++;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
lines.push("}");
|
|
250
|
+
return lines.join("\n");
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Map a JSON Schema type to a protobuf type.
|
|
255
|
+
* @param fieldName - the property name in the parent schema, used to derive nested message names
|
|
256
|
+
* @param schema - the JSON Schema describing this field's type
|
|
257
|
+
* @param parentName - the name of the enclosing protobuf message, used for nested message naming
|
|
258
|
+
* @param allSchemas - all known JSON schemas, used to resolve nested references
|
|
259
|
+
* @param messages - accumulator map updated with any nested message definitions generated
|
|
260
|
+
* @returns the protobuf scalar or message type name for this field
|
|
261
|
+
*/
|
|
262
|
+
function jsonTypeToProto(
|
|
263
|
+
fieldName: string,
|
|
264
|
+
schema: JSONSchema7,
|
|
265
|
+
parentName: string,
|
|
266
|
+
allSchemas: Record<string, JSONSchema7>,
|
|
267
|
+
messages: Map<string, string>
|
|
268
|
+
): string {
|
|
269
|
+
if (schema.$ref) {
|
|
270
|
+
// Distinguish two ref shapes:
|
|
271
|
+
// - `#/components/schemas/<name>` points at a top-level schema in the
|
|
272
|
+
// OpenAPI components registry. The original behaviour was to emit
|
|
273
|
+
// the bare message name and trust that some other schema source
|
|
274
|
+
// defines it; preserve that to keep `componentsSchemaRef` passing.
|
|
275
|
+
// - `#/definitions/<name>` is the typescript-json-schema shape: refs
|
|
276
|
+
// are local to the same schema's `definitions` block. The compiler
|
|
277
|
+
// already hoists those into `allSchemas` for us. If the lookup
|
|
278
|
+
// misses, we have a genuinely-unresolvable inline ref (e.g. a
|
|
279
|
+
// dropped placeholder from a generic-class method) — fall back to
|
|
280
|
+
// `google.protobuf.Struct` so proto-loader doesn't reject the
|
|
281
|
+
// output.
|
|
282
|
+
const isComponentsRef = schema.$ref.startsWith("#/components/schemas/");
|
|
283
|
+
const rawRefName = schema.$ref.replace("#/definitions/", "").replace("#/components/schemas/", "");
|
|
284
|
+
let decodedRefName: string;
|
|
285
|
+
try {
|
|
286
|
+
decodedRefName = decodeURIComponent(rawRefName);
|
|
287
|
+
} catch {
|
|
288
|
+
decodedRefName = rawRefName;
|
|
289
|
+
}
|
|
290
|
+
const msgName = schemaToMessageName(rawRefName);
|
|
291
|
+
const targetSchema = allSchemas[rawRefName] || allSchemas[decodedRefName];
|
|
292
|
+
if (!messages.has(msgName) && targetSchema) {
|
|
293
|
+
messages.set(msgName, ""); // placeholder to break recursion cycles
|
|
294
|
+
messages.set(msgName, jsonSchemaToMessage(msgName, targetSchema, allSchemas, messages));
|
|
295
|
+
}
|
|
296
|
+
if (!isComponentsRef && !targetSchema && !messages.has(msgName)) {
|
|
297
|
+
return "google.protobuf.Struct";
|
|
298
|
+
}
|
|
299
|
+
return msgName;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
switch (schema.type) {
|
|
303
|
+
case "string":
|
|
304
|
+
if (schema.format === "date-time" || schema.format === "date") return "string"; // Timestamps as ISO strings
|
|
305
|
+
if (schema.format === "int64") return "int64";
|
|
306
|
+
return "string";
|
|
307
|
+
case "number":
|
|
308
|
+
if (schema.format === "float") return "float";
|
|
309
|
+
if (schema.format === "int32" || schema.format === "integer") return "int32";
|
|
310
|
+
if (schema.format === "int64") return "int64";
|
|
311
|
+
return "double";
|
|
312
|
+
case "integer":
|
|
313
|
+
if (schema.format === "int64") return "int64";
|
|
314
|
+
return "int32";
|
|
315
|
+
case "boolean":
|
|
316
|
+
return "bool";
|
|
317
|
+
case "object":
|
|
318
|
+
if (schema.properties) {
|
|
319
|
+
// Nested message
|
|
320
|
+
const nestedName = `${parentName}${fieldName.charAt(0).toUpperCase() + fieldName.slice(1)}`;
|
|
321
|
+
if (!messages.has(nestedName)) {
|
|
322
|
+
messages.set(nestedName, jsonSchemaToMessage(nestedName, schema, allSchemas, messages));
|
|
323
|
+
}
|
|
324
|
+
return nestedName;
|
|
325
|
+
}
|
|
326
|
+
return "google.protobuf.Struct";
|
|
327
|
+
case "array":
|
|
328
|
+
// Handled by caller
|
|
329
|
+
return jsonTypeToProto(fieldName, (schema.items as JSONSchema7) || {}, parentName, allSchemas, messages);
|
|
330
|
+
default:
|
|
331
|
+
return "google.protobuf.Struct";
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Enum support
|
|
335
|
+
if (schema.enum) {
|
|
336
|
+
return "string"; // Map enums to strings for simplicity
|
|
337
|
+
}
|
|
338
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "nodenext",
|
|
5
|
+
"outDir": "./lib",
|
|
6
|
+
"rootDir": "./src",
|
|
7
|
+
"strict": false,
|
|
8
|
+
"declaration": true,
|
|
9
|
+
"sourceMap": true,
|
|
10
|
+
"isolatedModules": true,
|
|
11
|
+
"experimentalDecorators": false,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"moduleResolution": "nodenext",
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"declarationMap": true,
|
|
16
|
+
"useDefineForClassFields": true,
|
|
17
|
+
"strictPropertyInitialization": false,
|
|
18
|
+
"lib": [
|
|
19
|
+
"ES2022",
|
|
20
|
+
"ESNext.Decorators"
|
|
21
|
+
],
|
|
22
|
+
"types": [
|
|
23
|
+
"node"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"include": [
|
|
27
|
+
"src/**/*"
|
|
28
|
+
],
|
|
29
|
+
"exclude": [
|
|
30
|
+
"**/node_modules",
|
|
31
|
+
"src/**/*.spec.ts"
|
|
32
|
+
]
|
|
33
|
+
}
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/// <reference types="vitest" />
|
|
2
|
+
|
|
3
|
+
import { defineConfig } from "vite";
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
clearScreen: false,
|
|
7
|
+
test: {
|
|
8
|
+
allowOnly: true,
|
|
9
|
+
testTimeout: 20000,
|
|
10
|
+
coverage: {
|
|
11
|
+
enabled: true,
|
|
12
|
+
provider: "v8",
|
|
13
|
+
include: ["src/**/*.ts"],
|
|
14
|
+
exclude: ["src/**/*.spec.ts", "src/index.ts"],
|
|
15
|
+
reporter: ["lcov", "html", "text"]
|
|
16
|
+
},
|
|
17
|
+
reporters: "verbose",
|
|
18
|
+
include: ["src/**/*.spec.ts"]
|
|
19
|
+
}
|
|
20
|
+
});
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://webda.io/schemas/webda.module.v4.json",
|
|
3
|
+
"beans": {},
|
|
4
|
+
"deployers": {},
|
|
5
|
+
"moddas": {
|
|
6
|
+
"Webda/GrpcService": {
|
|
7
|
+
"Import": "lib/grpcservice.service:GrpcService",
|
|
8
|
+
"Schema": {
|
|
9
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
10
|
+
"additionalProperties": false,
|
|
11
|
+
"description": "Parameters for the gRPC service",
|
|
12
|
+
"properties": {
|
|
13
|
+
"operations": {
|
|
14
|
+
"default": [
|
|
15
|
+
"*"
|
|
16
|
+
],
|
|
17
|
+
"description": "List of operations to include/exclude\nSupports wildcards and negation: [\"*\", \"!User.Delete\"]",
|
|
18
|
+
"items": {
|
|
19
|
+
"type": "string"
|
|
20
|
+
},
|
|
21
|
+
"type": "array"
|
|
22
|
+
},
|
|
23
|
+
"packageName": {
|
|
24
|
+
"default": "webda",
|
|
25
|
+
"description": "Protobuf package name",
|
|
26
|
+
"type": "string"
|
|
27
|
+
},
|
|
28
|
+
"protoFile": {
|
|
29
|
+
"default": ".webda/app.proto",
|
|
30
|
+
"description": "Path to the generated .proto file",
|
|
31
|
+
"type": "string"
|
|
32
|
+
},
|
|
33
|
+
"type": {
|
|
34
|
+
"description": "Type of the service",
|
|
35
|
+
"type": "string"
|
|
36
|
+
},
|
|
37
|
+
"openapi": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"additionalProperties": true
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"required": [
|
|
43
|
+
"type"
|
|
44
|
+
],
|
|
45
|
+
"type": "object",
|
|
46
|
+
"title": "GrpcService"
|
|
47
|
+
},
|
|
48
|
+
"Configuration": "lib/grpcservice.service:GrpcServiceParameters",
|
|
49
|
+
"commands": {
|
|
50
|
+
"build": {
|
|
51
|
+
"description": "Generate protobuf definition from operations",
|
|
52
|
+
"method": "build",
|
|
53
|
+
"args": {},
|
|
54
|
+
"requires": [
|
|
55
|
+
"rest-domain"
|
|
56
|
+
],
|
|
57
|
+
"phase": "resolved"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"models": {},
|
|
63
|
+
"schemas": {
|
|
64
|
+
"Webda/BinaryFile": {
|
|
65
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
66
|
+
"WebdaSchema": true,
|
|
67
|
+
"additionalProperties": false,
|
|
68
|
+
"description": "Represent a file to store",
|
|
69
|
+
"properties": {
|
|
70
|
+
"challenge": {
|
|
71
|
+
"description": "Will be computed by the service\n\nhash of the content prefixed by 'WEBDA'",
|
|
72
|
+
"type": "string"
|
|
73
|
+
},
|
|
74
|
+
"hash": {
|
|
75
|
+
"description": "Will be computed by the service\n\nhash of the content",
|
|
76
|
+
"type": "string"
|
|
77
|
+
},
|
|
78
|
+
"metadata": {
|
|
79
|
+
"description": "Metadatas stored along with the binary"
|
|
80
|
+
},
|
|
81
|
+
"mimetype": {
|
|
82
|
+
"description": "Mimetype of the binary",
|
|
83
|
+
"type": "string"
|
|
84
|
+
},
|
|
85
|
+
"name": {
|
|
86
|
+
"description": "Current name",
|
|
87
|
+
"type": "string"
|
|
88
|
+
},
|
|
89
|
+
"originalname": {
|
|
90
|
+
"description": "Original name",
|
|
91
|
+
"type": "string"
|
|
92
|
+
},
|
|
93
|
+
"size": {
|
|
94
|
+
"description": "Size of the binary",
|
|
95
|
+
"type": "number"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"required": [
|
|
99
|
+
"mimetype",
|
|
100
|
+
"name",
|
|
101
|
+
"size"
|
|
102
|
+
],
|
|
103
|
+
"type": "object",
|
|
104
|
+
"title": "BinaryFile"
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"behaviors": {},
|
|
108
|
+
"capabilities": {
|
|
109
|
+
"grpc": "Webda/GrpcService"
|
|
110
|
+
}
|
|
111
|
+
}
|