@webda/grpc 4.0.0-beta.5 → 4.0.0-beta.6
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 +3 -3
- package/CHANGELOG.md +23 -0
- package/package.json +5 -5
- package/src/query-statements.spec.ts +91 -0
package/.webda/cache
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"sourceDigest": "
|
|
2
|
+
"sourceDigest": "2434da489c662daa01eb691dba3180bf",
|
|
3
3
|
"moduleDigest": "f6610a7c821cec29a3cdef273083e886",
|
|
4
4
|
"generator": {
|
|
5
|
-
"@webda/compiler": "4.0.0-beta.
|
|
6
|
-
"@webda/content-mapper": "4.0.0-beta.
|
|
5
|
+
"@webda/compiler": "4.0.0-beta.6",
|
|
6
|
+
"@webda/content-mapper": "4.0.0-beta.6"
|
|
7
7
|
}
|
|
8
8
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [4.0.0-beta.6](https://github.com/loopingz/webda.io/compare/grpc-v4.0.0-beta.5...grpc-v4.0.0-beta.6) (2026-10-09)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### ⚠ BREAKING CHANGES
|
|
7
|
+
|
|
8
|
+
* **ql:** DELETE, UPDATE, SELECT, SET and WHERE are reserved uppercase keywords; Query.type is required; parse().toString() prints the canonical query instead of the source tokens; the root parse rule is now `(statement | filterQuery) EOF` for code walking the ANTLR tree.
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* **ql:** WebdaQL DELETE/UPDATE/SELECT statements, bulk deleteMany/updateMany, filter-only Query operations ([#818](https://github.com/loopingz/webda.io/issues/818)) ([add9503](https://github.com/loopingz/webda.io/commit/add95031aff982cd69a635c519b4ddaa6874ecbe))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Dependencies
|
|
16
|
+
|
|
17
|
+
* The following workspace dependencies were updated
|
|
18
|
+
* devDependencies
|
|
19
|
+
* @webda/compiler bumped to 4.0.0-beta.6
|
|
20
|
+
* @webda/core bumped to 4.0.0-beta.6
|
|
21
|
+
* @webda/test bumped to 4.0.0-beta.6
|
|
22
|
+
* @webda/utils bumped to 4.0.0-beta.6
|
|
23
|
+
* peerDependencies
|
|
24
|
+
* @webda/core bumped from ^4.0.0-beta.1 to ^4.0.0-beta.6
|
|
25
|
+
|
|
3
26
|
## [4.0.0-beta.5](https://github.com/loopingz/webda.io/compare/grpc-v4.0.0-beta.4...grpc-v4.0.0-beta.5) (2026-10-08)
|
|
4
27
|
|
|
5
28
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webda/grpc",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.6",
|
|
4
4
|
"description": "gRPC transport for Webda.io — exposes operations as gRPC services",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
"@vitest/coverage-v8": "^4.1.2",
|
|
17
17
|
"vite": "^6.0.0",
|
|
18
18
|
"vitest": "^4.0.0",
|
|
19
|
-
"@webda/core": "^4.0.0-beta.
|
|
20
|
-
"@webda/
|
|
21
|
-
"@webda/test": "^4.0.0-beta.
|
|
22
|
-
"@webda/
|
|
19
|
+
"@webda/core": "^4.0.0-beta.6",
|
|
20
|
+
"@webda/compiler": "^4.0.0-beta.6",
|
|
21
|
+
"@webda/test": "^4.0.0-beta.6",
|
|
22
|
+
"@webda/utils": "^4.0.0-beta.6"
|
|
23
23
|
},
|
|
24
24
|
"webda": {
|
|
25
25
|
"namespace": "Webda",
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { suite, test } from "@webda/test";
|
|
2
|
+
import * as assert from "assert";
|
|
3
|
+
import {
|
|
4
|
+
CoreModel,
|
|
5
|
+
DomainService,
|
|
6
|
+
DomainServiceParameters,
|
|
7
|
+
MemoryRepository,
|
|
8
|
+
registerOperation,
|
|
9
|
+
registerRepository,
|
|
10
|
+
registerSchema,
|
|
11
|
+
useApplication
|
|
12
|
+
} from "@webda/core";
|
|
13
|
+
import { WebdaApplicationTest } from "@webda/core/lib/test/application.js";
|
|
14
|
+
import { GrpcService } from "./grpcservice.service.js";
|
|
15
|
+
import { GrpcStatus } from "./grpc-stream.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Model open to everyone, queried through a real DomainService operation
|
|
19
|
+
*/
|
|
20
|
+
class GrpcNote extends CoreModel {
|
|
21
|
+
title: string = "";
|
|
22
|
+
static canAct(): boolean {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
GrpcNote.registerSerializer();
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The gRPC unary dispatch with the real core: a Query operation takes a filter only
|
|
30
|
+
*/
|
|
31
|
+
@suite
|
|
32
|
+
class GrpcQueryStatementsTest extends WebdaApplicationTest {
|
|
33
|
+
/**
|
|
34
|
+
* @returns an application without any configured service
|
|
35
|
+
*/
|
|
36
|
+
getTestConfiguration(): any {
|
|
37
|
+
return { services: {} };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Send one message through the gRPC unary handler
|
|
42
|
+
* @param query - the query field of the request
|
|
43
|
+
* @returns the response or the gRPC error status
|
|
44
|
+
*/
|
|
45
|
+
async unary(query: string): Promise<{ response?: any; status?: number; message?: string }> {
|
|
46
|
+
const service: any = Object.create(GrpcService.prototype);
|
|
47
|
+
const result: { response?: any; status?: number; message?: string } = {};
|
|
48
|
+
const stream = {
|
|
49
|
+
onMessage: (callback: (message: any) => void) => callback({ query }),
|
|
50
|
+
sendUnary: (response: any) => (result.response = response),
|
|
51
|
+
sendError: (status: number, message: string) => {
|
|
52
|
+
result.status = status;
|
|
53
|
+
result.message = message;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
await service.handleUnary(stream, "GrpcNotes.Query", {});
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@test
|
|
61
|
+
async queryRpcTakesAFilterOnly() {
|
|
62
|
+
const schema = { type: "object", properties: { query: { type: "string" } } };
|
|
63
|
+
useApplication().getSchemas()["grpcSearchRequest"] = schema;
|
|
64
|
+
try {
|
|
65
|
+
registerSchema("grpcSearchRequest", schema);
|
|
66
|
+
} catch {
|
|
67
|
+
// already registered
|
|
68
|
+
}
|
|
69
|
+
this.registerService(new DomainService("GrpcDomain", new DomainServiceParameters().load({})));
|
|
70
|
+
registerRepository(GrpcNote, new MemoryRepository(GrpcNote, ["uuid"]));
|
|
71
|
+
await GrpcNote.create({ uuid: "n1", title: "keep" } as any);
|
|
72
|
+
registerOperation("GrpcNotes.Query", {
|
|
73
|
+
service: "GrpcDomain",
|
|
74
|
+
method: "modelQuery",
|
|
75
|
+
input: "grpcSearchRequest",
|
|
76
|
+
output: "void",
|
|
77
|
+
context: { model: GrpcNote }
|
|
78
|
+
} as any);
|
|
79
|
+
for (const query of ["DELETE", "DELETE WHERE uuid = 'n1'", "UPDATE SET title = 'pwned'", "SELECT title"]) {
|
|
80
|
+
const res = await this.unary(query);
|
|
81
|
+
assert.strictEqual(res.status, GrpcStatus.INVALID_ARGUMENT, `${query}: ${res.message}`);
|
|
82
|
+
}
|
|
83
|
+
assert.strictEqual(((await GrpcNote.ref("n1").get()) as any).title, "keep");
|
|
84
|
+
const ok = await this.unary("title = 'keep'");
|
|
85
|
+
assert.strictEqual(ok.status, undefined, ok.message);
|
|
86
|
+
assert.deepStrictEqual(
|
|
87
|
+
ok.response.results.map((n: any) => n.uuid),
|
|
88
|
+
["n1"]
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
}
|