@fonoster/sipnet 0.27.0 → 0.30.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.
- package/dist/acls/updateAcl.d.ts +0 -19
- package/dist/acls/updateAcl.js +5 -4
- package/dist/agents/buildService.js +4 -2
- package/dist/agents/operations.d.ts +3 -2
- package/dist/agents/operations.js +5 -4
- package/dist/domains/buildService.js +4 -2
- package/dist/domains/operations.d.ts +3 -2
- package/dist/domains/operations.js +5 -4
- package/dist/numbers/buildService.d.ts +3 -1
- package/dist/numbers/buildService.js +6 -3
- package/dist/numbers/convertToRoutrNumber.d.ts +6 -2
- package/dist/numbers/convertToRoutrNumber.js +8 -4
- package/dist/numbers/createNumber.d.ts +3 -1
- package/dist/numbers/createNumber.js +13 -4
- package/dist/numbers/engineRouting.d.ts +29 -0
- package/dist/numbers/engineRouting.js +44 -0
- package/dist/numbers/getNumber.d.ts +0 -19
- package/dist/numbers/getNumber.js +6 -6
- package/dist/numbers/index.d.ts +2 -0
- package/dist/numbers/index.js +16 -0
- package/dist/numbers/repointNumbers.d.ts +49 -0
- package/dist/numbers/repointNumbers.js +83 -0
- package/dist/numbers/repointNumbersCli.d.ts +1 -0
- package/dist/numbers/repointNumbersCli.js +106 -0
- package/dist/numbers/updateNumber.d.ts +4 -2
- package/dist/numbers/updateNumber.js +20 -7
- package/dist/resources/checkRefs.d.ts +26 -0
- package/dist/resources/checkRefs.js +138 -0
- package/dist/resources/createResource.d.ts +2 -1
- package/dist/resources/createResource.js +5 -2
- package/dist/resources/updateResource.d.ts +2 -1
- package/dist/resources/updateResource.js +7 -2
- package/dist/trunks/buildService.js +4 -2
- package/dist/trunks/operations.d.ts +10 -3
- package/dist/trunks/operations.js +40 -4
- package/package.json +8 -8
package/dist/acls/updateAcl.d.ts
CHANGED
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
3
|
-
* http://github.com/fonoster/fonoster
|
|
4
|
-
*
|
|
5
|
-
* This file is part of Fonoster
|
|
6
|
-
*
|
|
7
|
-
* Licensed under the MIT License (the "License");
|
|
8
|
-
* you may not use this file except in compliance with
|
|
9
|
-
* the License. You may obtain a copy of the License at
|
|
10
|
-
*
|
|
11
|
-
* https://opensource.org/licenses/MIT
|
|
12
|
-
*
|
|
13
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
* See the License for the specific language governing permissions and
|
|
17
|
-
* limitations under the License.
|
|
18
|
-
*/
|
|
19
|
-
import { GrpcErrorMessage } from "@fonoster/common";
|
|
20
1
|
import { AclsApi } from "@fonoster/types";
|
|
21
2
|
declare function updateAcl(api: AclsApi): (call: {
|
|
22
3
|
request: unknown;
|
package/dist/acls/updateAcl.js
CHANGED
|
@@ -29,15 +29,16 @@ exports.updateAcl = updateAcl;
|
|
|
29
29
|
* limitations under the License.
|
|
30
30
|
*/
|
|
31
31
|
const common_1 = require("@fonoster/common");
|
|
32
|
+
const identity_1 = require("@fonoster/identity");
|
|
32
33
|
const logger_1 = require("@fonoster/logger");
|
|
33
34
|
const logger = (0, logger_1.getLogger)({ service: "sipnet", filePath: __filename });
|
|
34
35
|
function updateAcl(api) {
|
|
35
|
-
const fn = (call
|
|
36
|
+
const fn = (call) => __awaiter(this, void 0, void 0, function* () {
|
|
36
37
|
const { request } = call;
|
|
37
38
|
const accessKeyId = (0, common_1.getAccessKeyIdFromCall)(call);
|
|
38
39
|
logger.verbose("call to updateAcl", Object.assign(Object.assign({}, request), { accessKeyId }));
|
|
39
|
-
|
|
40
|
-
callback(null, response);
|
|
40
|
+
return yield api.updateAcl(Object.assign(Object.assign({}, request), { deny: ["0.0.0.0/0"] }));
|
|
41
41
|
});
|
|
42
|
-
|
|
42
|
+
// Only the caller's own ACLs can be updated, like every other resource.
|
|
43
|
+
return (0, common_1.withErrorHandlingAndValidation)((0, identity_1.withAccess)(fn, ((ref) => api.getAcl(ref))), common_1.Validators.updateAclRequestSchema);
|
|
43
44
|
}
|
|
@@ -23,9 +23,11 @@ exports.buildService = buildService;
|
|
|
23
23
|
* limitations under the License.
|
|
24
24
|
*/
|
|
25
25
|
const sdk_1 = __importDefault(require("@routr/sdk"));
|
|
26
|
+
const checkRefs_1 = require("../resources/checkRefs");
|
|
26
27
|
const operations_1 = require("./operations");
|
|
27
28
|
function buildService(clientOptions) {
|
|
28
29
|
const client = new sdk_1.default.Agents(clientOptions);
|
|
30
|
+
const checkRefs = (0, checkRefs_1.createCheckRefs)((0, checkRefs_1.createRefLookups)(clientOptions));
|
|
29
31
|
return {
|
|
30
32
|
definition: {
|
|
31
33
|
serviceName: "Agents",
|
|
@@ -34,8 +36,8 @@ function buildService(clientOptions) {
|
|
|
34
36
|
proto: "agents.proto"
|
|
35
37
|
},
|
|
36
38
|
handlers: {
|
|
37
|
-
createAgent: (0, operations_1.createAgent)(client),
|
|
38
|
-
updateAgent: (0, operations_1.updateAgent)(client),
|
|
39
|
+
createAgent: (0, operations_1.createAgent)(client, checkRefs),
|
|
40
|
+
updateAgent: (0, operations_1.updateAgent)(client, checkRefs),
|
|
39
41
|
getAgent: (0, operations_1.getAgent)(client),
|
|
40
42
|
listAgents: (0, operations_1.listAgents)(client),
|
|
41
43
|
deleteAgent: (0, operations_1.deleteAgent)(client)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { AgentsApi } from "@fonoster/types";
|
|
2
|
-
|
|
2
|
+
import { CheckRefs } from "../resources/checkRefs";
|
|
3
|
+
declare function createAgent(agents: AgentsApi, checkRefs?: CheckRefs): (call: {
|
|
3
4
|
request: unknown;
|
|
4
5
|
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
5
|
-
declare function updateAgent(agents: AgentsApi): (call: {
|
|
6
|
+
declare function updateAgent(agents: AgentsApi, checkRefs?: CheckRefs): (call: {
|
|
6
7
|
request: unknown;
|
|
7
8
|
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
8
9
|
declare function getAgent(agents: AgentsApi): (call: {
|
|
@@ -24,17 +24,18 @@ exports.updateAgent = updateAgent;
|
|
|
24
24
|
* limitations under the License.
|
|
25
25
|
*/
|
|
26
26
|
const common_1 = require("@fonoster/common");
|
|
27
|
+
const checkRefs_1 = require("../resources/checkRefs");
|
|
27
28
|
const createResource_1 = require("../resources/createResource");
|
|
28
29
|
const deleteResource_1 = require("../resources/deleteResource");
|
|
29
30
|
const getResource_1 = require("../resources/getResource");
|
|
30
31
|
const listResources_1 = require("../resources/listResources");
|
|
31
32
|
const updateResource_1 = require("../resources/updateResource");
|
|
32
33
|
const RESOURCE = "Agent";
|
|
33
|
-
function createAgent(agents) {
|
|
34
|
-
return (0, createResource_1.createResource)(agents, RESOURCE, common_1.Validators.createAgentRequestSchema);
|
|
34
|
+
function createAgent(agents, checkRefs) {
|
|
35
|
+
return (0, createResource_1.createResource)(agents, RESOURCE, common_1.Validators.createAgentRequestSchema, (0, checkRefs_1.refsChecker)(checkRefs, checkRefs_1.agentRefs));
|
|
35
36
|
}
|
|
36
|
-
function updateAgent(agents) {
|
|
37
|
-
return (0, updateResource_1.updateResource)(agents, RESOURCE, common_1.Validators.updateAgentRequestSchema);
|
|
37
|
+
function updateAgent(agents, checkRefs) {
|
|
38
|
+
return (0, updateResource_1.updateResource)(agents, RESOURCE, common_1.Validators.updateAgentRequestSchema, (0, checkRefs_1.refsChecker)(checkRefs, checkRefs_1.agentRefs));
|
|
38
39
|
}
|
|
39
40
|
function getAgent(agents) {
|
|
40
41
|
return (0, getResource_1.getResource)(agents, RESOURCE);
|
|
@@ -23,9 +23,11 @@ exports.buildService = buildService;
|
|
|
23
23
|
* limitations under the License.
|
|
24
24
|
*/
|
|
25
25
|
const sdk_1 = __importDefault(require("@routr/sdk"));
|
|
26
|
+
const checkRefs_1 = require("../resources/checkRefs");
|
|
26
27
|
const operations_1 = require("./operations");
|
|
27
28
|
function buildService(clientOptions) {
|
|
28
29
|
const client = new sdk_1.default.Domains(clientOptions);
|
|
30
|
+
const checkRefs = (0, checkRefs_1.createCheckRefs)((0, checkRefs_1.createRefLookups)(clientOptions));
|
|
29
31
|
return {
|
|
30
32
|
definition: {
|
|
31
33
|
serviceName: "Domains",
|
|
@@ -34,8 +36,8 @@ function buildService(clientOptions) {
|
|
|
34
36
|
proto: "domains.proto"
|
|
35
37
|
},
|
|
36
38
|
handlers: {
|
|
37
|
-
createDomain: (0, operations_1.createDomain)(client),
|
|
38
|
-
updateDomain: (0, operations_1.updateDomain)(client),
|
|
39
|
+
createDomain: (0, operations_1.createDomain)(client, checkRefs),
|
|
40
|
+
updateDomain: (0, operations_1.updateDomain)(client, checkRefs),
|
|
39
41
|
getDomain: (0, operations_1.getDomain)(client),
|
|
40
42
|
listDomains: (0, operations_1.listDomains)(client),
|
|
41
43
|
deleteDomain: (0, operations_1.deleteDomain)(client)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { DomainsApi } from "@fonoster/types";
|
|
2
|
-
|
|
2
|
+
import { CheckRefs } from "../resources/checkRefs";
|
|
3
|
+
declare function createDomain(domains: DomainsApi, checkRefs?: CheckRefs): (call: {
|
|
3
4
|
request: unknown;
|
|
4
5
|
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
5
|
-
declare function updateDomain(domains: DomainsApi): (call: {
|
|
6
|
+
declare function updateDomain(domains: DomainsApi, checkRefs?: CheckRefs): (call: {
|
|
6
7
|
request: unknown;
|
|
7
8
|
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
8
9
|
declare function getDomain(domains: DomainsApi): (call: {
|
|
@@ -24,17 +24,18 @@ exports.updateDomain = updateDomain;
|
|
|
24
24
|
* limitations under the License.
|
|
25
25
|
*/
|
|
26
26
|
const common_1 = require("@fonoster/common");
|
|
27
|
+
const checkRefs_1 = require("../resources/checkRefs");
|
|
27
28
|
const createResource_1 = require("../resources/createResource");
|
|
28
29
|
const deleteResource_1 = require("../resources/deleteResource");
|
|
29
30
|
const getResource_1 = require("../resources/getResource");
|
|
30
31
|
const listResources_1 = require("../resources/listResources");
|
|
31
32
|
const updateResource_1 = require("../resources/updateResource");
|
|
32
33
|
const RESOURCE = "Domain";
|
|
33
|
-
function createDomain(domains) {
|
|
34
|
-
return (0, createResource_1.createResource)(domains, RESOURCE, common_1.Validators.createDomainRequestSchema);
|
|
34
|
+
function createDomain(domains, checkRefs) {
|
|
35
|
+
return (0, createResource_1.createResource)(domains, RESOURCE, common_1.Validators.createDomainRequestSchema, (0, checkRefs_1.refsChecker)(checkRefs, checkRefs_1.domainRefs));
|
|
35
36
|
}
|
|
36
|
-
function updateDomain(domains) {
|
|
37
|
-
return (0, updateResource_1.updateResource)(domains, RESOURCE, common_1.Validators.updateDomainRequestSchema);
|
|
37
|
+
function updateDomain(domains, checkRefs) {
|
|
38
|
+
return (0, updateResource_1.updateResource)(domains, RESOURCE, common_1.Validators.updateDomainRequestSchema, (0, checkRefs_1.refsChecker)(checkRefs, checkRefs_1.domainRefs));
|
|
38
39
|
}
|
|
39
40
|
function getDomain(domains) {
|
|
40
41
|
return (0, getResource_1.getResource)(domains, RESOURCE);
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import { NumberPreconditionsCheck } from "@fonoster/common";
|
|
20
20
|
import { ClientOptions } from "../types";
|
|
21
|
-
|
|
21
|
+
import { NumberRouting } from "./engineRouting";
|
|
22
|
+
/** `routing` picks the peer app-linked numbers point at (default: the media-node peer). */
|
|
23
|
+
declare function buildService(clientOptions: ClientOptions, checkNumberPreconditions: NumberPreconditionsCheck, routing?: NumberRouting): {
|
|
22
24
|
definition: {
|
|
23
25
|
serviceName: string;
|
|
24
26
|
pckg: string;
|
|
@@ -5,13 +5,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.buildService = buildService;
|
|
7
7
|
const sdk_1 = __importDefault(require("@routr/sdk"));
|
|
8
|
+
const checkRefs_1 = require("../resources/checkRefs");
|
|
8
9
|
const createNumber_1 = require("./createNumber");
|
|
9
10
|
const getNumber_1 = require("./getNumber");
|
|
10
11
|
const listNumbers_1 = require("./listNumbers");
|
|
11
12
|
const operations_1 = require("./operations");
|
|
12
13
|
const updateNumber_1 = require("./updateNumber");
|
|
13
|
-
|
|
14
|
+
/** `routing` picks the peer app-linked numbers point at (default: the media-node peer). */
|
|
15
|
+
function buildService(clientOptions, checkNumberPreconditions, routing) {
|
|
14
16
|
const client = new sdk_1.default.Numbers(clientOptions);
|
|
17
|
+
const checkRefs = (0, checkRefs_1.createCheckRefs)((0, checkRefs_1.createRefLookups)(clientOptions));
|
|
15
18
|
return {
|
|
16
19
|
definition: {
|
|
17
20
|
serviceName: "Numbers",
|
|
@@ -20,8 +23,8 @@ function buildService(clientOptions, checkNumberPreconditions) {
|
|
|
20
23
|
proto: "numbers.proto"
|
|
21
24
|
},
|
|
22
25
|
handlers: {
|
|
23
|
-
createNumber: (0, createNumber_1.createNumber)(client, checkNumberPreconditions),
|
|
24
|
-
updateNumber: (0, updateNumber_1.updateNumber)(client, checkNumberPreconditions),
|
|
26
|
+
createNumber: (0, createNumber_1.createNumber)(client, checkNumberPreconditions, routing, checkRefs),
|
|
27
|
+
updateNumber: (0, updateNumber_1.updateNumber)(client, checkNumberPreconditions, routing, checkRefs),
|
|
25
28
|
getNumber: (0, getNumber_1.getNumber)(client),
|
|
26
29
|
listNumbers: (0, listNumbers_1.listNumbers)(client),
|
|
27
30
|
deleteNumber: (0, operations_1.deleteNumber)(client)
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { CreateNumberRequest, UpdateNumberRequest } from "@fonoster/types";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* `appPeerAor` is the peer an app-linked number routes to: the media-node peer by default (see
|
|
4
|
+
* engineRouting.ts).
|
|
5
|
+
*/
|
|
6
|
+
declare function convertToRoutrNumber(number: CreateNumberRequest, accessKeyId: string, appPeerAor?: string): {
|
|
3
7
|
name: string;
|
|
4
8
|
telUrl: string;
|
|
5
9
|
aorLink: string;
|
|
@@ -13,7 +17,7 @@ declare function convertToRoutrNumber(number: CreateNumberRequest, accessKeyId:
|
|
|
13
17
|
trunkRef: string;
|
|
14
18
|
extended: Record<string, unknown>;
|
|
15
19
|
};
|
|
16
|
-
declare function convertToRoutrNumberUpdate(number: UpdateNumberRequest): {
|
|
20
|
+
declare function convertToRoutrNumberUpdate(number: UpdateNumberRequest, appPeerAor?: string): {
|
|
17
21
|
ref: string;
|
|
18
22
|
name: string;
|
|
19
23
|
aorLink: string;
|
|
@@ -21,8 +21,12 @@ exports.convertToRoutrNumberUpdate = convertToRoutrNumberUpdate;
|
|
|
21
21
|
* limitations under the License.
|
|
22
22
|
*/
|
|
23
23
|
const common_1 = require("@fonoster/common");
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
/**
|
|
25
|
+
* `appPeerAor` is the peer an app-linked number routes to: the media-node peer by default (see
|
|
26
|
+
* engineRouting.ts).
|
|
27
|
+
*/
|
|
28
|
+
function convertToRoutrNumber(number, accessKeyId, appPeerAor = common_1.ROUTR_DEFAULT_PEER_AOR) {
|
|
29
|
+
const aorLink = number.appRef ? appPeerAor : number.agentAor;
|
|
26
30
|
return {
|
|
27
31
|
name: number.name,
|
|
28
32
|
telUrl: number.telUrl,
|
|
@@ -42,11 +46,11 @@ function convertToRoutrNumber(number, accessKeyId) {
|
|
|
42
46
|
extended: { accessKeyId }
|
|
43
47
|
};
|
|
44
48
|
}
|
|
45
|
-
function convertToRoutrNumberUpdate(number) {
|
|
49
|
+
function convertToRoutrNumberUpdate(number, appPeerAor = common_1.ROUTR_DEFAULT_PEER_AOR) {
|
|
46
50
|
let aorLink;
|
|
47
51
|
let extraHeaders = [];
|
|
48
52
|
if (number.appRef) {
|
|
49
|
-
aorLink =
|
|
53
|
+
aorLink = appPeerAor;
|
|
50
54
|
extraHeaders.push({
|
|
51
55
|
name: common_1.APP_REF_HEADER,
|
|
52
56
|
value: number.appRef
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import { GrpcErrorMessage, NumberPreconditionsCheck } from "@fonoster/common";
|
|
20
20
|
import { NumbersApi } from "@fonoster/types";
|
|
21
|
-
|
|
21
|
+
import { CheckRefs } from "../resources/checkRefs";
|
|
22
|
+
import { NumberRouting } from "./engineRouting";
|
|
23
|
+
declare function createNumber(api: NumbersApi, checkNumberPreconditions: NumberPreconditionsCheck, routing?: NumberRouting, checkRefs?: CheckRefs): (call: {
|
|
22
24
|
request: unknown;
|
|
23
25
|
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
24
26
|
export { createNumber };
|
|
@@ -30,16 +30,25 @@ exports.createNumber = createNumber;
|
|
|
30
30
|
*/
|
|
31
31
|
const common_1 = require("@fonoster/common");
|
|
32
32
|
const logger_1 = require("@fonoster/logger");
|
|
33
|
+
const checkRefs_1 = require("../resources/checkRefs");
|
|
33
34
|
const convertToRoutrNumber_1 = require("./convertToRoutrNumber");
|
|
34
35
|
const logger = (0, logger_1.getLogger)({ service: "sipnet", filePath: __filename });
|
|
35
|
-
function createNumber(api, checkNumberPreconditions) {
|
|
36
|
+
function createNumber(api, checkNumberPreconditions, routing, checkRefs) {
|
|
36
37
|
const fn = (call, callback) => __awaiter(this, void 0, void 0, function* () {
|
|
37
38
|
const { request } = call;
|
|
38
|
-
// Validates that the appRef or agentAor exists in the system
|
|
39
|
-
yield checkNumberPreconditions(request);
|
|
40
39
|
const accessKeyId = (0, common_1.getAccessKeyIdFromCall)(call);
|
|
40
|
+
// Validates that the appRef exists in the caller's workspace (RV-B4)
|
|
41
|
+
yield checkNumberPreconditions(Object.assign(Object.assign({}, request), { accessKeyId }));
|
|
42
|
+
// ...and the trunk too (H7)
|
|
43
|
+
yield (checkRefs === null || checkRefs === void 0 ? void 0 : checkRefs(accessKeyId, (0, checkRefs_1.numberRefs)(request)));
|
|
41
44
|
logger.verbose("call to createNumber", Object.assign(Object.assign({}, request), { accessKeyId }));
|
|
42
|
-
const
|
|
45
|
+
const appPeerAor = routing && request.appRef
|
|
46
|
+
? yield routing.aorFor({
|
|
47
|
+
appRef: request.appRef,
|
|
48
|
+
telUrl: request.telUrl
|
|
49
|
+
})
|
|
50
|
+
: undefined;
|
|
51
|
+
const response = yield api.createNumber((0, convertToRoutrNumber_1.convertToRoutrNumber)(request, accessKeyId, appPeerAor));
|
|
43
52
|
callback(null, response);
|
|
44
53
|
});
|
|
45
54
|
return (0, common_1.withErrorHandlingAndValidation)(fn, common_1.Validators.createNumberRequestSchema);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where app-linked numbers point (add-media-node 4.1). Asterisk is retired (cleanbreak CB-B3):
|
|
3
|
+
* every app-linked number goes to the media-node peer that Go media nodes register under with
|
|
4
|
+
* least-sessions. `rebuild` is the only engine left; the type stays so repoint reports keep
|
|
5
|
+
* their shape.
|
|
6
|
+
*/
|
|
7
|
+
export type VoiceEngine = "rebuild";
|
|
8
|
+
export type EngineRoutingConfig = {
|
|
9
|
+
/** The media-node peer AOR (default sip:medianode@default). */
|
|
10
|
+
mediaNodeAor?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare const MEDIA_NODE_PEER_AOR = "sip:medianode@default";
|
|
13
|
+
/** The AOR of the retired Asterisk peer, for moving numbers created before the rebuild. */
|
|
14
|
+
export declare const LEGACY_ASTERISK_PEER_AOR = "sip:voice@default";
|
|
15
|
+
export type NumberRouting = {
|
|
16
|
+
/** The engine for an app-linked number. */
|
|
17
|
+
engineFor(target: {
|
|
18
|
+
appRef: string;
|
|
19
|
+
telUrl?: string;
|
|
20
|
+
}): Promise<VoiceEngine>;
|
|
21
|
+
/** The peer AOR (Number.aorLink) for an app-linked number. */
|
|
22
|
+
aorFor(target: {
|
|
23
|
+
appRef: string;
|
|
24
|
+
telUrl?: string;
|
|
25
|
+
}): Promise<string>;
|
|
26
|
+
/** The peer AOR of an engine. */
|
|
27
|
+
aorOf(engine: VoiceEngine): string;
|
|
28
|
+
};
|
|
29
|
+
export declare function createNumberRouting(config?: EngineRoutingConfig): NumberRouting;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.LEGACY_ASTERISK_PEER_AOR = exports.MEDIA_NODE_PEER_AOR = void 0;
|
|
13
|
+
exports.createNumberRouting = createNumberRouting;
|
|
14
|
+
/**
|
|
15
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
16
|
+
* http://github.com/fonoster/fonoster
|
|
17
|
+
*
|
|
18
|
+
* This file is part of Fonoster
|
|
19
|
+
*
|
|
20
|
+
* Licensed under the MIT License (the "License");
|
|
21
|
+
* you may not use this file except in compliance with
|
|
22
|
+
* the License. You may obtain a copy of the License at
|
|
23
|
+
*
|
|
24
|
+
* https://opensource.org/licenses/MIT
|
|
25
|
+
*
|
|
26
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
27
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
28
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
29
|
+
* See the License for the specific language governing permissions and
|
|
30
|
+
* limitations under the License.
|
|
31
|
+
*/
|
|
32
|
+
const common_1 = require("@fonoster/common");
|
|
33
|
+
exports.MEDIA_NODE_PEER_AOR = common_1.ROUTR_DEFAULT_PEER_AOR;
|
|
34
|
+
/** The AOR of the retired Asterisk peer, for moving numbers created before the rebuild. */
|
|
35
|
+
exports.LEGACY_ASTERISK_PEER_AOR = "sip:voice@default";
|
|
36
|
+
function createNumberRouting(config = {}) {
|
|
37
|
+
var _a;
|
|
38
|
+
const aor = (_a = config.mediaNodeAor) !== null && _a !== void 0 ? _a : exports.MEDIA_NODE_PEER_AOR;
|
|
39
|
+
return {
|
|
40
|
+
engineFor: () => __awaiter(this, void 0, void 0, function* () { return "rebuild"; }),
|
|
41
|
+
aorFor: () => __awaiter(this, void 0, void 0, function* () { return aor; }),
|
|
42
|
+
aorOf: () => aor
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
3
|
-
* http://github.com/fonoster/fonoster
|
|
4
|
-
*
|
|
5
|
-
* This file is part of Fonoster
|
|
6
|
-
*
|
|
7
|
-
* Licensed under the MIT License (the "License");
|
|
8
|
-
* you may not use this file except in compliance with
|
|
9
|
-
* the License. You may obtain a copy of the License at
|
|
10
|
-
*
|
|
11
|
-
* https://opensource.org/licenses/MIT
|
|
12
|
-
*
|
|
13
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
* See the License for the specific language governing permissions and
|
|
17
|
-
* limitations under the License.
|
|
18
|
-
*/
|
|
19
|
-
import { GrpcErrorMessage } from "@fonoster/common";
|
|
20
1
|
import { NumbersApi } from "@fonoster/types";
|
|
21
2
|
declare function getNumber(api: NumbersApi): (call: {
|
|
22
3
|
request: unknown;
|
|
@@ -29,16 +29,16 @@ exports.getNumber = getNumber;
|
|
|
29
29
|
* limitations under the License.
|
|
30
30
|
*/
|
|
31
31
|
const common_1 = require("@fonoster/common");
|
|
32
|
+
const identity_1 = require("@fonoster/identity");
|
|
32
33
|
const logger_1 = require("@fonoster/logger");
|
|
33
34
|
const convertToFonosterNumber_1 = require("./convertToFonosterNumber");
|
|
34
35
|
const logger = (0, logger_1.getLogger)({ service: "sipnet", filePath: __filename });
|
|
35
36
|
function getNumber(api) {
|
|
36
|
-
const fn = (call
|
|
37
|
-
const {
|
|
38
|
-
const { ref } = request;
|
|
37
|
+
const fn = (call) => __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
const { ref } = call.request;
|
|
39
39
|
logger.verbose("call to getNumber", { ref });
|
|
40
|
-
|
|
41
|
-
callback(null, (0, convertToFonosterNumber_1.convertToFonosterNumber)(response));
|
|
40
|
+
return (0, convertToFonosterNumber_1.convertToFonosterNumber)(yield api.getNumber(ref));
|
|
42
41
|
});
|
|
43
|
-
|
|
42
|
+
// Only the caller's own numbers can be read, like every other resource.
|
|
43
|
+
return (0, common_1.withErrorHandlingAndValidation)((0, identity_1.withAccess)(fn, ((ref) => api.getNumber(ref))), common_1.Validators.emptySchema);
|
|
44
44
|
}
|
package/dist/numbers/index.d.ts
CHANGED
package/dist/numbers/index.js
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
17
|
exports.buildNumbersService = void 0;
|
|
4
18
|
/**
|
|
@@ -21,3 +35,5 @@ exports.buildNumbersService = void 0;
|
|
|
21
35
|
*/
|
|
22
36
|
var buildService_1 = require("./buildService");
|
|
23
37
|
Object.defineProperty(exports, "buildNumbersService", { enumerable: true, get: function () { return buildService_1.buildService; } });
|
|
38
|
+
__exportStar(require("./engineRouting"), exports);
|
|
39
|
+
__exportStar(require("./repointNumbers"), exports);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { NumberRouting, VoiceEngine } from "./engineRouting";
|
|
2
|
+
/** The slice of Routr's Numbers API that repointing needs (`new SDK.Numbers(...)` fits). */
|
|
3
|
+
export type RoutrNumbersClient = {
|
|
4
|
+
listNumbers(request: {
|
|
5
|
+
pageSize: number;
|
|
6
|
+
pageToken?: string;
|
|
7
|
+
}): Promise<{
|
|
8
|
+
items: RoutrNumber[];
|
|
9
|
+
nextPageToken?: string;
|
|
10
|
+
}>;
|
|
11
|
+
updateNumber(request: {
|
|
12
|
+
ref: string;
|
|
13
|
+
name: string;
|
|
14
|
+
aorLink: string;
|
|
15
|
+
extraHeaders?: {
|
|
16
|
+
name: string;
|
|
17
|
+
value: string;
|
|
18
|
+
}[];
|
|
19
|
+
}): Promise<unknown>;
|
|
20
|
+
};
|
|
21
|
+
export type RoutrNumber = {
|
|
22
|
+
ref: string;
|
|
23
|
+
name: string;
|
|
24
|
+
telUrl: string;
|
|
25
|
+
aorLink?: string;
|
|
26
|
+
extraHeaders?: {
|
|
27
|
+
name: string;
|
|
28
|
+
value: string;
|
|
29
|
+
}[];
|
|
30
|
+
};
|
|
31
|
+
export type RepointChange = {
|
|
32
|
+
ref: string;
|
|
33
|
+
telUrl: string;
|
|
34
|
+
appRef: string;
|
|
35
|
+
engine: VoiceEngine;
|
|
36
|
+
from?: string;
|
|
37
|
+
to: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Moves app-linked Numbers to the peer routing says (the media nodes). Routr stores `aorLink` on
|
|
41
|
+
* each Number, so numbers created for Asterisk keep pointing at it until they are rewritten;
|
|
42
|
+
* agent-linked Numbers are never touched. Returns what changed (or would,
|
|
43
|
+
* with `dryRun`).
|
|
44
|
+
*/
|
|
45
|
+
export declare function repointNumbers(client: RoutrNumbersClient, routing: NumberRouting, options?: {
|
|
46
|
+
appRefs?: string[];
|
|
47
|
+
dryRun?: boolean;
|
|
48
|
+
pageSize?: number;
|
|
49
|
+
}): Promise<RepointChange[]>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.repointNumbers = repointNumbers;
|
|
13
|
+
/**
|
|
14
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
15
|
+
* http://github.com/fonoster/fonoster
|
|
16
|
+
*
|
|
17
|
+
* This file is part of Fonoster
|
|
18
|
+
*
|
|
19
|
+
* Licensed under the MIT License (the "License");
|
|
20
|
+
* you may not use this file except in compliance with
|
|
21
|
+
* the License. You may obtain a copy of the License at
|
|
22
|
+
*
|
|
23
|
+
* https://opensource.org/licenses/MIT
|
|
24
|
+
*
|
|
25
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
26
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
27
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
28
|
+
* See the License for the specific language governing permissions and
|
|
29
|
+
* limitations under the License.
|
|
30
|
+
*/
|
|
31
|
+
const common_1 = require("@fonoster/common");
|
|
32
|
+
/**
|
|
33
|
+
* Moves app-linked Numbers to the peer routing says (the media nodes). Routr stores `aorLink` on
|
|
34
|
+
* each Number, so numbers created for Asterisk keep pointing at it until they are rewritten;
|
|
35
|
+
* agent-linked Numbers are never touched. Returns what changed (or would,
|
|
36
|
+
* with `dryRun`).
|
|
37
|
+
*/
|
|
38
|
+
function repointNumbers(client_1, routing_1) {
|
|
39
|
+
return __awaiter(this, arguments, void 0, function* (client, routing, options = {}) {
|
|
40
|
+
var _a, _b, _c;
|
|
41
|
+
const changes = [];
|
|
42
|
+
let pageToken;
|
|
43
|
+
const numbers = [];
|
|
44
|
+
do {
|
|
45
|
+
const page = yield client.listNumbers({
|
|
46
|
+
pageSize: (_a = options.pageSize) !== null && _a !== void 0 ? _a : 100,
|
|
47
|
+
pageToken
|
|
48
|
+
});
|
|
49
|
+
numbers.push(...page.items);
|
|
50
|
+
pageToken = page.nextPageToken || undefined;
|
|
51
|
+
} while (pageToken);
|
|
52
|
+
for (const n of numbers) {
|
|
53
|
+
// Header names are case-insensitive (sipnet writes x-app-ref; operators may write X-App-Ref).
|
|
54
|
+
const appRef = (_c = (_b = n.extraHeaders) === null || _b === void 0 ? void 0 : _b.find((h) => h.name.toLowerCase() === common_1.APP_REF_HEADER.toLowerCase())) === null || _c === void 0 ? void 0 : _c.value;
|
|
55
|
+
if (!appRef)
|
|
56
|
+
continue;
|
|
57
|
+
if (options.appRefs && !options.appRefs.includes(appRef))
|
|
58
|
+
continue;
|
|
59
|
+
const engine = yield routing.engineFor({ appRef, telUrl: n.telUrl });
|
|
60
|
+
const to = routing.aorOf(engine);
|
|
61
|
+
if (n.aorLink === to)
|
|
62
|
+
continue;
|
|
63
|
+
changes.push({
|
|
64
|
+
ref: n.ref,
|
|
65
|
+
telUrl: n.telUrl,
|
|
66
|
+
appRef,
|
|
67
|
+
engine,
|
|
68
|
+
from: n.aorLink,
|
|
69
|
+
to
|
|
70
|
+
});
|
|
71
|
+
if (!options.dryRun) {
|
|
72
|
+
// Routr's update needs the name; extra headers are kept as they are.
|
|
73
|
+
yield client.updateNumber({
|
|
74
|
+
ref: n.ref,
|
|
75
|
+
name: n.name,
|
|
76
|
+
aorLink: to,
|
|
77
|
+
extraHeaders: n.extraHeaders
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return changes;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
/**
|
|
49
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
50
|
+
* http://github.com/fonoster/fonoster
|
|
51
|
+
*
|
|
52
|
+
* This file is part of Fonoster
|
|
53
|
+
*
|
|
54
|
+
* Licensed under the MIT License (the "License");
|
|
55
|
+
* you may not use this file except in compliance with
|
|
56
|
+
* the License. You may obtain a copy of the License at
|
|
57
|
+
*
|
|
58
|
+
* https://opensource.org/licenses/MIT
|
|
59
|
+
*
|
|
60
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
61
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
62
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
63
|
+
* See the License for the specific language governing permissions and
|
|
64
|
+
* limitations under the License.
|
|
65
|
+
*/
|
|
66
|
+
const fs = __importStar(require("fs"));
|
|
67
|
+
const sdk_1 = __importDefault(require("@routr/sdk"));
|
|
68
|
+
const engineRouting_1 = require("./engineRouting");
|
|
69
|
+
const repointNumbers_1 = require("./repointNumbers");
|
|
70
|
+
/**
|
|
71
|
+
* Moves app-linked Numbers created before the rebuild (pointing at Asterisk's sip:voice@default)
|
|
72
|
+
* to the media-node peer:
|
|
73
|
+
*
|
|
74
|
+
* node dist/numbers/repointNumbersCli.js <routing.json> [--apply] [--app <ref>]...
|
|
75
|
+
*
|
|
76
|
+
* routing.json holds an EngineRoutingConfig ({ mediaNodeAor }); `{}` uses sip:medianode@default.
|
|
77
|
+
* Without --apply it only prints what would change. ROUTR_API_ENDPOINT (default routr:51907)
|
|
78
|
+
* points at Routr's API.
|
|
79
|
+
*/
|
|
80
|
+
function main(argv) {
|
|
81
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
82
|
+
var _a;
|
|
83
|
+
const file = argv[0];
|
|
84
|
+
if (!file) {
|
|
85
|
+
console.error("usage: repointNumbersCli <routing.json> [--apply] [--app <ref>]...");
|
|
86
|
+
process.exit(2);
|
|
87
|
+
}
|
|
88
|
+
const config = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
89
|
+
const appRefs = argv
|
|
90
|
+
.map((a, i) => (a === "--app" ? argv[i + 1] : undefined))
|
|
91
|
+
.filter((a) => !!a);
|
|
92
|
+
const client = new sdk_1.default.Numbers({
|
|
93
|
+
endpoint: (_a = process.env.ROUTR_API_ENDPOINT) !== null && _a !== void 0 ? _a : "routr:51907",
|
|
94
|
+
insecure: true
|
|
95
|
+
});
|
|
96
|
+
const changes = yield (0, repointNumbers_1.repointNumbers)(client, (0, engineRouting_1.createNumberRouting)(config), {
|
|
97
|
+
dryRun: !argv.includes("--apply"),
|
|
98
|
+
appRefs: appRefs.length ? appRefs : undefined
|
|
99
|
+
});
|
|
100
|
+
console.log(JSON.stringify({ applied: argv.includes("--apply"), changes }, null, 2));
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
main(process.argv.slice(2)).catch((e) => {
|
|
104
|
+
console.error(e.message);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
});
|
|
@@ -16,9 +16,11 @@
|
|
|
16
16
|
* See the License for the specific language governing permissions and
|
|
17
17
|
* limitations under the License.
|
|
18
18
|
*/
|
|
19
|
-
import {
|
|
19
|
+
import { NumberPreconditionsCheck } from "@fonoster/common";
|
|
20
20
|
import { NumbersApi } from "@fonoster/types";
|
|
21
|
-
|
|
21
|
+
import { CheckRefs } from "../resources/checkRefs";
|
|
22
|
+
import { NumberRouting } from "./engineRouting";
|
|
23
|
+
declare function updateNumber(api: NumbersApi, checkNumberPreconditions: NumberPreconditionsCheck, routing?: NumberRouting, checkRefs?: CheckRefs): (call: {
|
|
22
24
|
request: unknown;
|
|
23
25
|
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
24
26
|
export { updateNumber };
|
|
@@ -29,17 +29,30 @@ exports.updateNumber = updateNumber;
|
|
|
29
29
|
* limitations under the License.
|
|
30
30
|
*/
|
|
31
31
|
const common_1 = require("@fonoster/common");
|
|
32
|
+
const identity_1 = require("@fonoster/identity");
|
|
32
33
|
const logger_1 = require("@fonoster/logger");
|
|
34
|
+
const checkRefs_1 = require("../resources/checkRefs");
|
|
33
35
|
const convertToRoutrNumber_1 = require("./convertToRoutrNumber");
|
|
34
36
|
const logger = (0, logger_1.getLogger)({ service: "sipnet", filePath: __filename });
|
|
35
|
-
function updateNumber(api, checkNumberPreconditions) {
|
|
36
|
-
const fn = (call
|
|
37
|
+
function updateNumber(api, checkNumberPreconditions, routing, checkRefs) {
|
|
38
|
+
const fn = (call) => __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
var _a;
|
|
37
40
|
const { request } = call;
|
|
38
|
-
// Validates that the appRef
|
|
39
|
-
|
|
41
|
+
// Validates that the appRef exists in the caller's workspace (RV-B4)
|
|
42
|
+
const accessKeyId = (0, common_1.getAccessKeyIdFromCall)(call);
|
|
43
|
+
yield checkNumberPreconditions(Object.assign(Object.assign({}, request), { accessKeyId }));
|
|
44
|
+
// ...and the trunk too (H7)
|
|
45
|
+
yield (checkRefs === null || checkRefs === void 0 ? void 0 : checkRefs(accessKeyId, (0, checkRefs_1.numberRefs)(request)));
|
|
40
46
|
logger.verbose("call to updateNumber", Object.assign({}, request));
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
// The number's telUrl matters only for per-number pins, so it is read only with routing.
|
|
48
|
+
const appPeerAor = routing && request.appRef
|
|
49
|
+
? yield routing.aorFor({
|
|
50
|
+
appRef: request.appRef,
|
|
51
|
+
telUrl: (_a = (yield api.getNumber(request.ref))) === null || _a === void 0 ? void 0 : _a.telUrl
|
|
52
|
+
})
|
|
53
|
+
: undefined;
|
|
54
|
+
return yield api.updateNumber((0, convertToRoutrNumber_1.convertToRoutrNumberUpdate)(request, appPeerAor));
|
|
43
55
|
});
|
|
44
|
-
|
|
56
|
+
// Only the caller's own numbers can be updated, like every other resource.
|
|
57
|
+
return (0, common_1.withErrorHandlingAndValidation)((0, identity_1.withAccess)(fn, ((ref) => api.getNumber(ref))), common_1.Validators.updateNumberRequestSchema);
|
|
45
58
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ClientOptions } from "../types";
|
|
2
|
+
type RefKind = "Acl" | "Credentials" | "Domain" | "Number" | "Trunk";
|
|
3
|
+
type OwnedResource = {
|
|
4
|
+
extended?: Record<string, unknown> | null;
|
|
5
|
+
} | null | undefined;
|
|
6
|
+
type RefLookups = Record<RefKind, (ref: string) => Promise<OwnedResource>>;
|
|
7
|
+
/** One reference in a request: the request field, what it names and its value. */
|
|
8
|
+
type RefField = {
|
|
9
|
+
field: string;
|
|
10
|
+
kind: RefKind;
|
|
11
|
+
ref?: string | null;
|
|
12
|
+
};
|
|
13
|
+
type CheckRefs = (accessKeyId: string | undefined, refs: RefField[]) => Promise<void>;
|
|
14
|
+
/** A request's references, checked before it reaches Routr. */
|
|
15
|
+
type CheckRequestRefs<R> = (request: R, accessKeyId: string | undefined) => Promise<void>;
|
|
16
|
+
declare function createCheckRefs(lookups: Partial<RefLookups>): CheckRefs;
|
|
17
|
+
/** The production lookups: Routr's API, one client per kind. */
|
|
18
|
+
declare function createRefLookups(clientOptions: ClientOptions): RefLookups;
|
|
19
|
+
type Refs = Record<string, unknown>;
|
|
20
|
+
declare const agentRefs: (r: Refs) => RefField[];
|
|
21
|
+
declare const trunkRefs: (r: Refs) => RefField[];
|
|
22
|
+
declare const domainRefs: (r: Refs) => RefField[];
|
|
23
|
+
declare const numberRefs: (r: Refs) => RefField[];
|
|
24
|
+
/** The reference check for one resource type's requests. */
|
|
25
|
+
declare function refsChecker<R>(checkRefs: CheckRefs | undefined, refsOf: (request: Refs) => RefField[]): CheckRequestRefs<R> | undefined;
|
|
26
|
+
export { agentRefs, CheckRefs, CheckRequestRefs, createCheckRefs, createRefLookups, domainRefs, numberRefs, RefField, RefKind, RefLookups, refsChecker, trunkRefs };
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.trunkRefs = exports.numberRefs = exports.domainRefs = exports.agentRefs = void 0;
|
|
16
|
+
exports.createCheckRefs = createCheckRefs;
|
|
17
|
+
exports.createRefLookups = createRefLookups;
|
|
18
|
+
exports.refsChecker = refsChecker;
|
|
19
|
+
/**
|
|
20
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
21
|
+
* http://github.com/fonoster/fonoster
|
|
22
|
+
*
|
|
23
|
+
* This file is part of Fonoster
|
|
24
|
+
*
|
|
25
|
+
* Licensed under the MIT License (the "License");
|
|
26
|
+
* you may not use this file except in compliance with
|
|
27
|
+
* the License. You may obtain a copy of the License at
|
|
28
|
+
*
|
|
29
|
+
* https://opensource.org/licenses/MIT
|
|
30
|
+
*
|
|
31
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
32
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
33
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
34
|
+
* See the License for the specific language governing permissions and
|
|
35
|
+
* limitations under the License.
|
|
36
|
+
*/
|
|
37
|
+
const common_1 = require("@fonoster/common");
|
|
38
|
+
const grpc_js_1 = require("@grpc/grpc-js");
|
|
39
|
+
const sdk_1 = __importDefault(require("@routr/sdk"));
|
|
40
|
+
const isNotFound = (e) => (e === null || e === void 0 ? void 0 : e.code) === grpc_js_1.status.NOT_FOUND;
|
|
41
|
+
function createCheckRefs(lookups) {
|
|
42
|
+
return (accessKeyId, refs) => __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
var _a;
|
|
44
|
+
const given = refs.filter((r) => typeof r.ref === "string" && r.ref !== "");
|
|
45
|
+
if (given.length === 0)
|
|
46
|
+
return;
|
|
47
|
+
if (!accessKeyId) {
|
|
48
|
+
throw new common_1.GrpcError(grpc_js_1.status.PERMISSION_DENIED, "the caller's workspace is required to reference other resources");
|
|
49
|
+
}
|
|
50
|
+
for (const { field, kind, ref } of given) {
|
|
51
|
+
const lookup = lookups[kind];
|
|
52
|
+
if (!lookup)
|
|
53
|
+
throw new Error(`no lookup for ${kind} references`);
|
|
54
|
+
let resource;
|
|
55
|
+
try {
|
|
56
|
+
resource = yield lookup(ref);
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
if (!isNotFound(e))
|
|
60
|
+
throw e;
|
|
61
|
+
resource = undefined;
|
|
62
|
+
}
|
|
63
|
+
// Another workspace's resource is reported like a missing one, so refs of other
|
|
64
|
+
// workspaces are not confirmed.
|
|
65
|
+
if (((_a = resource === null || resource === void 0 ? void 0 : resource.extended) === null || _a === void 0 ? void 0 : _a.accessKeyId) !== accessKeyId) {
|
|
66
|
+
throw new common_1.GrpcError(grpc_js_1.status.INVALID_ARGUMENT, `${field} ${ref} not found`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/** The production lookups: Routr's API, one client per kind. */
|
|
72
|
+
function createRefLookups(clientOptions) {
|
|
73
|
+
const acls = new sdk_1.default.Acls(clientOptions);
|
|
74
|
+
const credentials = new sdk_1.default.Credentials(clientOptions);
|
|
75
|
+
const domains = new sdk_1.default.Domains(clientOptions);
|
|
76
|
+
const numbers = new sdk_1.default.Numbers(clientOptions);
|
|
77
|
+
const trunks = new sdk_1.default.Trunks(clientOptions);
|
|
78
|
+
return {
|
|
79
|
+
Acl: (ref) => acls.getAcl(ref),
|
|
80
|
+
Credentials: (ref) => credentials.getCredentials(ref),
|
|
81
|
+
Domain: (ref) => domains.getDomain(ref),
|
|
82
|
+
Number: (ref) => numbers.getNumber(ref),
|
|
83
|
+
Trunk: (ref) => trunks.getTrunk(ref)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const agentRefs = (r) => [
|
|
87
|
+
{ field: "domainRef", kind: "Domain", ref: r.domainRef },
|
|
88
|
+
{
|
|
89
|
+
field: "credentialsRef",
|
|
90
|
+
kind: "Credentials",
|
|
91
|
+
ref: r.credentialsRef
|
|
92
|
+
}
|
|
93
|
+
];
|
|
94
|
+
exports.agentRefs = agentRefs;
|
|
95
|
+
const trunkRefs = (r) => [
|
|
96
|
+
{
|
|
97
|
+
field: "accessControlListRef",
|
|
98
|
+
kind: "Acl",
|
|
99
|
+
ref: r.accessControlListRef
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
field: "inboundCredentialsRef",
|
|
103
|
+
kind: "Credentials",
|
|
104
|
+
ref: r.inboundCredentialsRef
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
field: "outboundCredentialsRef",
|
|
108
|
+
kind: "Credentials",
|
|
109
|
+
ref: r.outboundCredentialsRef
|
|
110
|
+
}
|
|
111
|
+
];
|
|
112
|
+
exports.trunkRefs = trunkRefs;
|
|
113
|
+
const domainRefs = (r) => {
|
|
114
|
+
var _a;
|
|
115
|
+
return [
|
|
116
|
+
{
|
|
117
|
+
field: "accessControlListRef",
|
|
118
|
+
kind: "Acl",
|
|
119
|
+
ref: r.accessControlListRef
|
|
120
|
+
},
|
|
121
|
+
...((_a = r.egressPolicies) !== null && _a !== void 0 ? _a : []).map((p, i) => ({
|
|
122
|
+
field: `egressPolicies[${i}].numberRef`,
|
|
123
|
+
kind: "Number",
|
|
124
|
+
ref: p === null || p === void 0 ? void 0 : p.numberRef
|
|
125
|
+
}))
|
|
126
|
+
];
|
|
127
|
+
};
|
|
128
|
+
exports.domainRefs = domainRefs;
|
|
129
|
+
const numberRefs = (r) => [
|
|
130
|
+
{ field: "trunkRef", kind: "Trunk", ref: r.trunkRef }
|
|
131
|
+
];
|
|
132
|
+
exports.numberRefs = numberRefs;
|
|
133
|
+
/** The reference check for one resource type's requests. */
|
|
134
|
+
function refsChecker(checkRefs, refsOf) {
|
|
135
|
+
return checkRefs
|
|
136
|
+
? (request, accessKeyId) => checkRefs(accessKeyId, refsOf(request))
|
|
137
|
+
: undefined;
|
|
138
|
+
}
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import { GrpcErrorMessage } from "@fonoster/common";
|
|
20
20
|
import { z } from "zod";
|
|
21
|
-
|
|
21
|
+
import { CheckRequestRefs } from "./checkRefs";
|
|
22
|
+
declare function createResource<T, R, U>(api: U, resource: string, schema: z.ZodSchema, checkRefs?: CheckRequestRefs<R>): (call: {
|
|
22
23
|
request: unknown;
|
|
23
24
|
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
24
25
|
export { createResource };
|
|
@@ -31,11 +31,14 @@ exports.createResource = createResource;
|
|
|
31
31
|
const common_1 = require("@fonoster/common");
|
|
32
32
|
const logger_1 = require("@fonoster/logger");
|
|
33
33
|
const logger = (0, logger_1.getLogger)({ service: "sipnet", filePath: __filename });
|
|
34
|
-
function createResource(api, resource, schema) {
|
|
34
|
+
function createResource(api, resource, schema, checkRefs) {
|
|
35
35
|
const fn = (call, callback) => __awaiter(this, void 0, void 0, function* () {
|
|
36
36
|
const { request } = call;
|
|
37
37
|
const accessKeyId = (0, common_1.getAccessKeyIdFromCall)(call);
|
|
38
|
-
|
|
38
|
+
// Never the request itself: credentials and trunks carry passwords (M11).
|
|
39
|
+
logger.verbose(`call to create${resource}`, { accessKeyId });
|
|
40
|
+
// Referenced credentials, ACLs, domains, numbers and trunks must be the caller's (H7).
|
|
41
|
+
yield (checkRefs === null || checkRefs === void 0 ? void 0 : checkRefs(request, accessKeyId));
|
|
39
42
|
const response = yield api[`create${resource}`](Object.assign(Object.assign({}, request), { extended: {
|
|
40
43
|
accessKeyId
|
|
41
44
|
} }));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
|
|
2
|
+
import { CheckRequestRefs } from "./checkRefs";
|
|
3
|
+
declare function updateResource<T, R, U>(api: U, resource: string, schema: z.ZodSchema, checkRefs?: CheckRequestRefs<R>): (call: {
|
|
3
4
|
request: unknown;
|
|
4
5
|
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
5
6
|
export { updateResource };
|
|
@@ -32,10 +32,15 @@ const common_1 = require("@fonoster/common");
|
|
|
32
32
|
const identity_1 = require("@fonoster/identity");
|
|
33
33
|
const logger_1 = require("@fonoster/logger");
|
|
34
34
|
const logger = (0, logger_1.getLogger)({ service: "sipnet", filePath: __filename });
|
|
35
|
-
function updateResource(api, resource, schema) {
|
|
35
|
+
function updateResource(api, resource, schema, checkRefs) {
|
|
36
36
|
const fn = (call) => __awaiter(this, void 0, void 0, function* () {
|
|
37
37
|
const { request } = call;
|
|
38
|
-
|
|
38
|
+
// Never the request itself: credentials and trunks carry passwords (M11).
|
|
39
|
+
logger.verbose(`call to update${resource}`, {
|
|
40
|
+
ref: request.ref
|
|
41
|
+
});
|
|
42
|
+
// Referenced credentials, ACLs, domains, numbers and trunks must be the caller's (H7).
|
|
43
|
+
yield (checkRefs === null || checkRefs === void 0 ? void 0 : checkRefs(request, (0, common_1.getAccessKeyIdFromCall)(call)));
|
|
39
44
|
return yield api[`update${resource}`](request);
|
|
40
45
|
});
|
|
41
46
|
return (0, common_1.withErrorHandlingAndValidation)((0, identity_1.withAccess)(fn, (ref) => api[`get${resource}`](ref)), schema);
|
|
@@ -23,9 +23,11 @@ exports.buildService = buildService;
|
|
|
23
23
|
* limitations under the License.
|
|
24
24
|
*/
|
|
25
25
|
const sdk_1 = __importDefault(require("@routr/sdk"));
|
|
26
|
+
const checkRefs_1 = require("../resources/checkRefs");
|
|
26
27
|
const operations_1 = require("./operations");
|
|
27
28
|
function buildService(clientOptions) {
|
|
28
29
|
const client = new sdk_1.default.Trunks(clientOptions);
|
|
30
|
+
const checkRefs = (0, checkRefs_1.createCheckRefs)((0, checkRefs_1.createRefLookups)(clientOptions));
|
|
29
31
|
return {
|
|
30
32
|
definition: {
|
|
31
33
|
serviceName: "Trunks",
|
|
@@ -34,8 +36,8 @@ function buildService(clientOptions) {
|
|
|
34
36
|
proto: "trunks.proto"
|
|
35
37
|
},
|
|
36
38
|
handlers: {
|
|
37
|
-
createTrunk: (0, operations_1.createTrunk)(client),
|
|
38
|
-
updateTrunk: (0, operations_1.updateTrunk)(client),
|
|
39
|
+
createTrunk: (0, operations_1.createTrunk)(client, checkRefs),
|
|
40
|
+
updateTrunk: (0, operations_1.updateTrunk)(client, checkRefs),
|
|
39
41
|
getTrunk: (0, operations_1.getTrunk)(client),
|
|
40
42
|
listTrunks: (0, operations_1.listTrunks)(client),
|
|
41
43
|
deleteTrunk: (0, operations_1.deleteTrunk)(client)
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import { TrunkApi } from "@fonoster/types";
|
|
2
|
-
|
|
1
|
+
import { TrunkApi, TrunkExtended, UpdateTrunkRequest } from "@fonoster/types";
|
|
2
|
+
import { CheckRefs } from "../resources/checkRefs";
|
|
3
|
+
declare function createTrunk(trunks: TrunkApi, checkRefs?: CheckRefs): (call: {
|
|
3
4
|
request: unknown;
|
|
4
5
|
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* A partial update: fields the request leaves blank keep their current value (proto3 sends ""
|
|
8
|
+
* and [] for fields not set, and Routr rejects a trunk without a name or inbound URI). Clearing
|
|
9
|
+
* the URIs or a reference through an update is therefore not possible; recreate the trunk.
|
|
10
|
+
*/
|
|
11
|
+
export declare function mergeTrunkUpdate(request: UpdateTrunkRequest, current: Partial<TrunkExtended>): UpdateTrunkRequest;
|
|
12
|
+
declare function updateTrunk(trunks: TrunkApi, checkRefs?: CheckRefs): (call: {
|
|
6
13
|
request: unknown;
|
|
7
14
|
}, callback: (error?: import("@fonoster/common").GrpcErrorMessage, response?: unknown) => void) => Promise<void>;
|
|
8
15
|
declare function getTrunk(trunks: TrunkApi): (call: {
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
2
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.mergeTrunkUpdate = mergeTrunkUpdate;
|
|
3
13
|
exports.createTrunk = createTrunk;
|
|
4
14
|
exports.deleteTrunk = deleteTrunk;
|
|
5
15
|
exports.getTrunk = getTrunk;
|
|
@@ -24,17 +34,43 @@ exports.updateTrunk = updateTrunk;
|
|
|
24
34
|
* limitations under the License.
|
|
25
35
|
*/
|
|
26
36
|
const common_1 = require("@fonoster/common");
|
|
37
|
+
const checkRefs_1 = require("../resources/checkRefs");
|
|
27
38
|
const createResource_1 = require("../resources/createResource");
|
|
28
39
|
const deleteResource_1 = require("../resources/deleteResource");
|
|
29
40
|
const getResource_1 = require("../resources/getResource");
|
|
30
41
|
const listResources_1 = require("../resources/listResources");
|
|
31
42
|
const updateResource_1 = require("../resources/updateResource");
|
|
32
43
|
const RESOURCE = "Trunk";
|
|
33
|
-
function createTrunk(trunks) {
|
|
34
|
-
return (0, createResource_1.createResource)(trunks, RESOURCE, common_1.Validators.createTrunkRequestSchema);
|
|
44
|
+
function createTrunk(trunks, checkRefs) {
|
|
45
|
+
return (0, createResource_1.createResource)(trunks, RESOURCE, common_1.Validators.createTrunkRequestSchema, (0, checkRefs_1.refsChecker)(checkRefs, checkRefs_1.trunkRefs));
|
|
35
46
|
}
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
const blank = (v) => v === undefined || v === null || v === "" || (Array.isArray(v) && !v.length);
|
|
48
|
+
/**
|
|
49
|
+
* A partial update: fields the request leaves blank keep their current value (proto3 sends ""
|
|
50
|
+
* and [] for fields not set, and Routr rejects a trunk without a name or inbound URI). Clearing
|
|
51
|
+
* the URIs or a reference through an update is therefore not possible; recreate the trunk.
|
|
52
|
+
*/
|
|
53
|
+
function mergeTrunkUpdate(request, current) {
|
|
54
|
+
const merged = Object.assign({}, request);
|
|
55
|
+
for (const key of [
|
|
56
|
+
"name",
|
|
57
|
+
"inboundUri",
|
|
58
|
+
"accessControlListRef",
|
|
59
|
+
"inboundCredentialsRef",
|
|
60
|
+
"outboundCredentialsRef",
|
|
61
|
+
"uris"
|
|
62
|
+
]) {
|
|
63
|
+
const value = current[key];
|
|
64
|
+
if (blank(merged[key]) && !blank(value))
|
|
65
|
+
merged[key] = value;
|
|
66
|
+
}
|
|
67
|
+
return merged;
|
|
68
|
+
}
|
|
69
|
+
function updateTrunk(trunks, checkRefs) {
|
|
70
|
+
const partial = Object.assign(Object.assign({}, trunks), { getTrunk: (ref) => trunks.getTrunk(ref), updateTrunk: (request) => __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
return trunks.updateTrunk(mergeTrunkUpdate(request, yield trunks.getTrunk(request.ref)));
|
|
72
|
+
}) });
|
|
73
|
+
return (0, updateResource_1.updateResource)(partial, RESOURCE, common_1.Validators.updateTrunkRequestSchema, (0, checkRefs_1.refsChecker)(checkRefs, checkRefs_1.trunkRefs));
|
|
38
74
|
}
|
|
39
75
|
function getTrunk(trunks) {
|
|
40
76
|
return (0, getResource_1.getResource)(trunks, RESOURCE);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fonoster/sipnet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "Routr-based SIP stack",
|
|
5
5
|
"author": "Pedro Sanders <psanders@fonoster.com>",
|
|
6
6
|
"homepage": "https://github.com/fonoster/fonoster#readme",
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
"fonoster": "./dist/index.js"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@fonoster/common": "^0.
|
|
24
|
-
"@fonoster/identity": "^0.
|
|
25
|
-
"@fonoster/logger": "^0.
|
|
26
|
-
"@fonoster/types": "^0.
|
|
27
|
-
"@grpc/grpc-js": "~1.
|
|
28
|
-
"@routr/sdk": "2.
|
|
23
|
+
"@fonoster/common": "^0.30.0",
|
|
24
|
+
"@fonoster/identity": "^0.30.0",
|
|
25
|
+
"@fonoster/logger": "^0.30.0",
|
|
26
|
+
"@fonoster/types": "^0.30.0",
|
|
27
|
+
"@grpc/grpc-js": "~1.14.6",
|
|
28
|
+
"@routr/sdk": "2.15.2",
|
|
29
29
|
"zod": "^3.23.8"
|
|
30
30
|
},
|
|
31
31
|
"files": [
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"bugs": {
|
|
42
42
|
"url": "https://github.com/fonoster/fonoster/issues"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "b59b06a3ef325abe3f188c0fb87cc22d50ed5471"
|
|
45
45
|
}
|