@routr/pgdata 2.15.3 → 2.16.0

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.
@@ -0,0 +1,5 @@
1
+ type Fields = Record<string, unknown>;
2
+ export declare function stripPresenceMarkers<T extends Fields>(request: T): T;
3
+ export declare function isPresent(value: unknown): boolean;
4
+ export declare function pickPresentFields<T extends Fields>(request: Fields, data: T): Partial<T>;
5
+ export {};
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stripPresenceMarkers = stripPresenceMarkers;
4
+ exports.isPresent = isPresent;
5
+ exports.pickPresentFields = pickPresentFields;
6
+ // The proto loader adds a synthetic oneof marker (e.g. `_name: "name"`) for
7
+ // every proto3 optional field that is set
8
+ function stripPresenceMarkers(request) {
9
+ return Object.fromEntries(Object.entries(request).filter(([key, value]) => !(key.startsWith("_") && value === key.slice(1))));
10
+ }
11
+ // Update requests are partial. Optional fields are absent unless sent, while
12
+ // repeated fields and messages always decode ([] and null), so an empty list
13
+ // or a null message means "keep what is stored"
14
+ function isPresent(value) {
15
+ if (value === undefined || value === null)
16
+ return false;
17
+ return Array.isArray(value) ? value.length > 0 : true;
18
+ }
19
+ // Keeps only the entries of the mapped data whose field the request carried
20
+ function pickPresentFields(request, data) {
21
+ return Object.fromEntries(Object.entries(data).filter(([key]) => isPresent(request[key])));
22
+ }
@@ -33,24 +33,26 @@ const pb_util_1 = require("pb-util");
33
33
  const common_1 = require("@routr/common");
34
34
  const utils_1 = require("../mappers/utils");
35
35
  const db_1 = require("../db");
36
+ const partial_1 = require("./partial");
36
37
  function update(operation, kind) {
37
38
  return (call, callback) => __awaiter(this, void 0, void 0, function* () {
38
39
  try {
39
- const { request } = call;
40
+ const request = (0, partial_1.stripPresenceMarkers)(call.request);
40
41
  if (request.extended) {
41
42
  request.extended = pb_util_1.struct.decode(request.extended);
42
43
  }
43
44
  const Manager = (0, utils_1.getManager)(kind);
44
45
  const manager = new Manager(request);
45
46
  manager.validOrThrowUpdate();
46
- if (kind === common_1.CommonConnect.Kind.DOMAIN && request.egressPolicy) {
47
+ // A non-empty list replaces the stored one; an empty list keeps it
48
+ if (kind === common_1.CommonConnect.Kind.DOMAIN && (0, partial_1.isPresent)(request.egressPolicies)) {
47
49
  yield db_1.prisma.egressPolicy.deleteMany({
48
50
  where: {
49
51
  domainRef: request.ref
50
52
  }
51
53
  });
52
54
  }
53
- if (kind === common_1.CommonConnect.Kind.TRUNK && request.uris) {
55
+ if (kind === common_1.CommonConnect.Kind.TRUNK && (0, partial_1.isPresent)(request.uris)) {
54
56
  yield db_1.prisma.trunkURI.deleteMany({
55
57
  where: {
56
58
  trunkRef: request.ref
@@ -61,7 +63,7 @@ function update(operation, kind) {
61
63
  where: {
62
64
  ref: request.ref
63
65
  },
64
- data: manager.mapToPrisma(),
66
+ data: (0, partial_1.pickPresentFields)(request, manager.mapToPrisma()),
65
67
  include: Manager.includeFields()
66
68
  }));
67
69
  if (objectFromDB.extended) {
@@ -19,7 +19,9 @@ class ACLManager extends manager_1.EntityManager {
19
19
  }
20
20
  validOrThrowUpdate() {
21
21
  common_1.CommonConnect.hasReferenceOrThrow(this.acl.ref);
22
- common_1.CommonConnect.isValidNameOrThrow(this.acl.name);
22
+ // Updates are partial, so only validate the name when it is sent
23
+ if (this.acl.name !== undefined)
24
+ common_1.CommonConnect.isValidNameOrThrow(this.acl.name);
23
25
  common_1.CommonConnect.hasValidACLRulesOrThrow(this.acl);
24
26
  }
25
27
  mapToPrisma() {
@@ -57,7 +57,9 @@ class AgentManager extends manager_1.EntityManager {
57
57
  }
58
58
  validOrThrowUpdate() {
59
59
  common_1.CommonConnect.hasReferenceOrThrow(this.agent.ref);
60
- common_1.CommonConnect.isValidNameOrThrow(this.agent.name);
60
+ // Updates are partial, so only validate the name when it is sent
61
+ if (this.agent.name !== undefined)
62
+ common_1.CommonConnect.isValidNameOrThrow(this.agent.name);
61
63
  }
62
64
  mapToPrisma() {
63
65
  var _a;
@@ -21,7 +21,9 @@ class CredentialsManager extends manager_1.EntityManager {
21
21
  }
22
22
  validOrThrowUpdate() {
23
23
  common_1.CommonConnect.hasReferenceOrThrow(this.credentials.ref);
24
- common_1.CommonConnect.isValidNameOrThrow(this.credentials.name);
24
+ // Updates are partial, so only validate the name when it is sent
25
+ if (this.credentials.name !== undefined)
26
+ common_1.CommonConnect.isValidNameOrThrow(this.credentials.name);
25
27
  common_1.CommonConnect.isValidUsernameOrThrow(this.credentials.username);
26
28
  }
27
29
  mapToPrisma() {
@@ -28,7 +28,9 @@ class DomainManager extends manager_1.EntityManager {
28
28
  }
29
29
  validOrThrowUpdate() {
30
30
  common_1.CommonConnect.hasReferenceOrThrow(this.domain.ref);
31
- common_1.CommonConnect.isValidNameOrThrow(this.domain.name);
31
+ // Updates are partial, so only validate the name when it is sent
32
+ if (this.domain.name !== undefined)
33
+ common_1.CommonConnect.isValidNameOrThrow(this.domain.name);
32
34
  }
33
35
  mapToPrisma() {
34
36
  var _a;
@@ -39,13 +39,15 @@ class NumberManager extends manager_1.EntityManager {
39
39
  }
40
40
  validOrThrowUpdate() {
41
41
  common_1.CommonConnect.hasReferenceOrThrow(this.number.ref);
42
- common_1.CommonConnect.isValidNameOrThrow(this.number.name);
42
+ // Updates are partial, so only validate the name when it is sent
43
+ if (this.number.name !== undefined)
44
+ common_1.CommonConnect.isValidNameOrThrow(this.number.name);
43
45
  common_1.CommonConnect.isValidAORLinkOrThrow(this.number.aorLink);
44
46
  common_1.CommonConnect.hasValidHeadersOrThrow(this.number.extraHeaders);
45
47
  common_1.CommonConnect.isValidSessionAffinityHeaderOrThrow(this.number.sessionAffinityHeader);
46
48
  }
47
49
  mapToPrisma() {
48
- return Object.assign(Object.assign({}, this.number), { apiVersion: "v2", trunkRef: this.number.trunkRef, sessionAffinityHeader: this.number.sessionAffinityHeader, extraHeaders: this.number.extraHeaders, createdAt: undefined, updatedAt: undefined, extended: this.number.extended });
50
+ return Object.assign(Object.assign({}, this.number), { apiVersion: "v2", trunkRef: this.number.trunkRef || null, sessionAffinityHeader: this.number.sessionAffinityHeader, extraHeaders: this.number.extraHeaders, createdAt: undefined, updatedAt: undefined, extended: this.number.extended });
49
51
  }
50
52
  static mapToDto(number) {
51
53
  return number
@@ -28,7 +28,9 @@ class PeerManager extends manager_1.EntityManager {
28
28
  }
29
29
  validOrThrowUpdate() {
30
30
  common_1.CommonConnect.hasReferenceOrThrow(this.peer.ref);
31
- common_1.CommonConnect.isValidNameOrThrow(this.peer.name);
31
+ // Updates are partial, so only validate the name when it is sent
32
+ if (this.peer.name !== undefined)
33
+ common_1.CommonConnect.isValidNameOrThrow(this.peer.name);
32
34
  common_1.CommonConnect.isValidUsernameOrThrow(this.peer.username);
33
35
  common_1.CommonConnect.isValidAOROrThrow(this.peer.aor);
34
36
  common_1.CommonConnect.isValidContactAddressOrThrow(this.peer.contactAddr);
@@ -28,7 +28,9 @@ class TrunkManager extends manager_1.EntityManager {
28
28
  }
29
29
  validOrThrowUpdate() {
30
30
  common_1.CommonConnect.hasReferenceOrThrow(this.trunk.ref);
31
- common_1.CommonConnect.isValidNameOrThrow(this.trunk.name);
31
+ // Updates are partial, so only validate the name when it is sent
32
+ if (this.trunk.name !== undefined)
33
+ common_1.CommonConnect.isValidNameOrThrow(this.trunk.name);
32
34
  common_1.CommonConnect.isValidInboundUriOrThrow(this.trunk.inboundUri);
33
35
  }
34
36
  mapToPrisma() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@routr/pgdata",
3
- "version": "2.15.3",
3
+ "version": "2.16.0",
4
4
  "description": "Postgres API Server for Routr Connect",
5
5
  "author": "Pedro Sanders <psanders@fonoster.com>",
6
6
  "homepage": "https://github.com/fonoster/routr#readme",
@@ -24,8 +24,8 @@
24
24
  "@fonoster/logger": "0.6.0",
25
25
  "@grpc/grpc-js": "~1.14.6",
26
26
  "@prisma/client": "^6.19.1",
27
- "@routr/common": "^2.15.3",
28
- "@routr/processor": "^2.15.3",
27
+ "@routr/common": "^2.16.0",
28
+ "@routr/processor": "^2.16.0",
29
29
  "google-protobuf": "^3.21.4",
30
30
  "grpc-health-check": "^2.1.0",
31
31
  "pb-util": "^1.0.3",
@@ -51,5 +51,5 @@
51
51
  "@types/validator": "^13.15.10",
52
52
  "prisma": "^6.19.1"
53
53
  },
54
- "gitHead": "30e73f1331f115b2dd9d02cdfdcf931dbeede36b"
54
+ "gitHead": "db8a2eeb4b3f57a7f6b632d8d3378ffe53fc6cfe"
55
55
  }