@webda/grpc 4.0.0-beta.4 → 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 +4 -4
- package/CHANGELOG.md +49 -0
- package/package.json +7 -7
- package/src/query-statements.spec.ts +91 -0
- package/webda.module.json +0 -4
package/.webda/cache
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"sourceDigest": "
|
|
3
|
-
"moduleDigest": "
|
|
2
|
+
"sourceDigest": "2434da489c662daa01eb691dba3180bf",
|
|
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,54 @@
|
|
|
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
|
+
|
|
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)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### ⚠ BREAKING CHANGES
|
|
30
|
+
|
|
31
|
+
* **core:** models defining canAct are now enforced on REST, gRPC and MCP operations; refused calls return 403. Query pages can be shorter than their LIMIT. OwnerModel ignores a client supplied _user. ResourceAcl.canAct signature changed to (context, action) and entries need a principal.
|
|
32
|
+
|
|
33
|
+
### Bug Fixes
|
|
34
|
+
|
|
35
|
+
* **core:** enforce model permissions on every transport, deny by default ([#810](https://github.com/loopingz/webda.io/issues/810)) ([24c1182](https://github.com/loopingz/webda.io/commit/24c11824f38999ef28ec7795c8af8d0ba862d9be))
|
|
36
|
+
* **packaging:** point every package's repository at its monorepo folder ([#812](https://github.com/loopingz/webda.io/issues/812)) ([3717b73](https://github.com/loopingz/webda.io/commit/3717b73c7a7b91348057d84c8e64ecf840c75cb1))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### Dependencies
|
|
40
|
+
|
|
41
|
+
* The following workspace dependencies were updated
|
|
42
|
+
* dependencies
|
|
43
|
+
* @webda/workout bumped to 4.0.0-beta.5
|
|
44
|
+
* devDependencies
|
|
45
|
+
* @webda/compiler bumped to 4.0.0-beta.5
|
|
46
|
+
* @webda/core bumped to 4.0.0-beta.5
|
|
47
|
+
* @webda/test bumped to 4.0.0-beta.5
|
|
48
|
+
* @webda/utils bumped to 4.0.0-beta.5
|
|
49
|
+
* peerDependencies
|
|
50
|
+
* @webda/core bumped from ^4.0.0-beta.1 to ^4.0.0-beta.5
|
|
51
|
+
|
|
3
52
|
## [4.0.0-beta.4](https://github.com/loopingz/webda.io/compare/grpc-v4.0.0-beta.3...grpc-v4.0.0-beta.4) (2026-10-08)
|
|
4
53
|
|
|
5
54
|
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
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",
|
|
7
7
|
"types": "lib/index.d.ts",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@grpc/proto-loader": "^0.7.0",
|
|
10
|
-
"@webda/workout": "4.0.0-beta.
|
|
10
|
+
"@webda/workout": "4.0.0-beta.5"
|
|
11
11
|
},
|
|
12
12
|
"peerDependencies": {
|
|
13
13
|
"@webda/core": "^4.0.0-beta.1"
|
|
@@ -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/
|
|
20
|
-
"@webda/
|
|
21
|
-
"@webda/test": "^4.0.0-beta.
|
|
22
|
-
"@webda/utils": "^4.0.0-beta.
|
|
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",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"license": "LGPL-3.0-only",
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|
|
33
|
-
"url": "https://github.com/loopingz/webda.io.git",
|
|
33
|
+
"url": "git+https://github.com/loopingz/webda.io.git",
|
|
34
34
|
"directory": "packages/grpc"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
@@ -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
|
+
}
|
package/webda.module.json
CHANGED
|
@@ -67,10 +67,6 @@
|
|
|
67
67
|
"additionalProperties": false,
|
|
68
68
|
"description": "Represent a file to store",
|
|
69
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
70
|
"hash": {
|
|
75
71
|
"description": "Will be computed by the service\n\nhash of the content",
|
|
76
72
|
"type": "string"
|