@push.rocks/smartnftables 2.5.2 → 3.0.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/changelog.md +31 -0
- package/dist_rust/smartnftables_linux_amd64_musl +0 -0
- package/dist_rust/smartnftables_linux_amd64_musl.tsrust-build.json +5 -5
- package/dist_rust/smartnftables_linux_arm64_musl +0 -0
- package/dist_rust/smartnftables_linux_arm64_musl.tsrust-build.json +5 -5
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/managed.egress.types.d.ts +69 -3
- package/package.json +6 -6
- package/readme.md +342 -61
- package/rust/src/egress.compile.rs +157 -76
- package/rust/src/egress.host.rs +104 -44
- package/rust/src/egress.hostgrant.rs +14 -14
- package/rust/src/egress.keys.rs +305 -0
- package/rust/src/egress.leased.rs +399 -0
- package/rust/src/egress.poolguard.rs +45 -0
- package/rust/src/egress.private.rs +197 -0
- package/rust/src/egress.published.rs +370 -0
- package/rust/src/egress.router.rs +64 -295
- package/rust/src/egress.rs +248 -17
- package/rust/src/egress.workloadgrant.rs +88 -0
- package/rust/src/egress_hostgrant_tests.rs +196 -47
- package/rust/src/egress_localplatform_tests.rs +204 -0
- package/rust/src/egress_localport_tests.rs +266 -0
- package/rust/src/egress_publishedrange_tests.rs +812 -0
- package/rust/src/egress_routerequivalence_tests.rs +448 -0
- package/rust/src/egress_tests.rs +132 -230
- package/rust/src/egress_workloadgrant_tests.rs +313 -0
- package/rust/src/owner.rs +77 -15
- package/rust/src/owner_host_traffic_tests.rs +4 -0
- package/rust/src/owner_hostgrant_traffic_tests.rs +9 -4
- package/rust/src/owner_identity_tests.rs +228 -80
- package/rust/src/owner_localplatform_tests.rs +274 -0
- package/rust/src/owner_localport_tests.rs +241 -0
- package/rust/src/owner_publishedrange_traffic_tests.rs +306 -0
- package/rust/src/owner_router_traffic_tests.rs +2 -0
- package/rust/src/owner_scale_traffic_tests.rs +383 -0
- package/rust/src/owner_tests.rs +15 -0
- package/rust/src/owner_workloadgrant_tests.rs +278 -0
- package/rust/src/policy.rs +29 -25
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/managed.egress.types.ts +71 -3
package/changelog.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-09-28 - 3.0.0
|
|
4
|
+
|
|
5
|
+
### Breaking Changes
|
|
6
|
+
|
|
7
|
+
- The schema-v2 `routerEgress` compiler now keeps private endpoints, directed rules and leased egress grants in named sets and maps behind a fixed set of rules, and every scope keeps its `publishedPorts` the same way (see Features). The policy API is additive and policy digests are unchanged, but the compiled graph of every `routerEgress` table and of every scope with publications changes: reconcile, inspection or release against such a table applied by 2.x returns `Conflict`, because the new engine does not adopt the old graph. Recover and release each such table with the exact previous engine and its retained intent and receipt, under a traffic fence, before upgrading. Tables of other scopes and without publications are unchanged.
|
|
8
|
+
- Rebalance the atomic replacement budget inside the unchanged 320,000-byte batch: the complete target (rules, chains and sets at most 100,000 bytes, plus set elements) may take 212,000 bytes beside a 107,520-byte handle-only deletion of the previous graph, instead of two fixed 100,000-byte halves for rules and elements. The hard ceiling is Linux's `sendmsg` limit, the socket send buffer (`net.core.wmem_max` doubled, 425,984 bytes by default); 320,000 bytes fits any `wmem_max` of at least 160,016.
|
|
9
|
+
- Raise the router's input bounds to 128 private endpoints and links, 1024 private rules and 1024 egress grants, and the publication bound of both scopes to 1024. Schema-v1 policies keep their bounds, digests and compiled bytes.
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
- Router: a node of 64 workloads, each with local DNS, public TCP and UDP egress, four platform endpoints and one to three publications, compiles about 66,000 rule bytes and 105,000 element bytes (89 such workloads fit), where 2.x held three. Private links, indices, names and source prefixes, directed rules, and per-kind and per-shape leased zone, return and flow maps, with the generation labels in two exact sets, replace the per-endpoint guard chains, per-rule grants, per-grant classifiers and admissions and the per-generation state chains; every lookup keeps the operands the rules compared, a key's link index is proven with the interface name through `private_link`, and a decision corpus of about 133,000 packets frozen from the 2.6.0 compiler is reproduced exactly. Owner verification admits absence (inverted) lookups and exact maps, and interval elements without a distinct last key.
|
|
14
|
+
- Add published port ranges to both hops of a schema-v2 publication: an optional `hostPortEnd` on `hostTransit.publishedPorts` and `transitPortEnd` on `routerEgress.publishedPorts` publish `port..end` with every port kept (the inside port must equal the first port). A range compiles to one interval match per classification, translation and admission and to address-only destination NAT, so it costs the same operations as one port. Inverted and one-port ranges, a range with a differing inside port, overlaps between publications of one protocol and overlaps with a leased source-port range on the translated address are refused.
|
|
15
|
+
- Add `symmetric` publications on both hops: the workload may open flows from its published address and port(s) toward unprotected space, NEW (a SYN-only TCP opening) or ESTABLISHED with ESTABLISHED replies, source-translated to the transit address and published transit port in the router and to `hostIp` and the published uplink port on the host, so outbound flows leave from the port clients reach. The admissions follow the capture barrier, so the protected union stays denied; a symmetric publication's inside ports may not overlap another publication's on the same address or, on the host, a leased range of its target address.
|
|
16
|
+
- Compile every publication, of both hops, as elements of CONSTANT concatenated interval sets and maps (the kernel's pipapo backend) behind a constant number of rules: at most eleven rules and four sets on the host and thirteen rules and six sets in the router, whatever the number of publications, instead of four and six rules per publication. Destination NAT is a map lookup (to address and port for one port, to the address alone for a range) and symmetric source NAT a map lookup to the outside address and port span. Owner verification now admits interval and map sets, reads back their concatenation, every element's bounds and data, and map lookups with their data register, so apply, inspection, adoption and recovery reject a changed element like a changed rule. Absent and empty publications, `hostPortEnd`, `transitPortEnd` and `symmetric` (and `symmetric: false`) keep the previous canonical policy and digest, and a scope without publications keeps its compiled bytes; a scope with publications compiles a different graph for the same digest.
|
|
17
|
+
|
|
18
|
+
### Maintenance
|
|
19
|
+
|
|
20
|
+
- Release tooling: pnpm 12.5.1, `@git.zone/cli` 7.3.0, `@git.zone/tsrust` 1.15.1, `@git.zone/tstest` 6.3.2, `@git.zone/tsrun` 3.0.1, `@types/node` 26.6.2 (pnpm 12.6.0 and `@types/node` 26.6.3 stay out until they clear the seven-day rule).
|
|
21
|
+
|
|
22
|
+
## 2026-09-25 - 2.6.0
|
|
23
|
+
|
|
24
|
+
### Features
|
|
25
|
+
|
|
26
|
+
- Add optional loopback TCP port owners to the schema-v2 `allocationPoolGuard` scope: `localTcpPortOwners` entries `{ address, port, uid }` (an exact IPv4 loopback host address, one port and one owning uid, at most 8) compile, ahead of the guard, an OUTPUT rule that rejects with a TCP reset every packet to that address and port from a socket whose uid differs (`meta skuid != uid`, after ordinary output destination NAT) and an INPUT rule that drops the address and port arriving on any interface but loopback. Owner verification now admits the TCP-reset `reject` expression and reads it back like every other operand, so the entries are verified on apply, retained, adopted, recovered and released with the table. Absent and empty keep the previous canonical policy, digest and compiled bytes. The native qualification guest loads the `nf_reject_ipv4`, `nf_reject_ipv6`, `nft_reject` and `nft_reject_inet` modules.
|
|
27
|
+
- Add optional host-local platform endpoints to the schema-v2 `hostTransit` scope: `localPlatformEndpoints` lists ids of `protection.platformEndpoints` the host serves on an exact address of its uplink or a handoff link (verified through rtnetlink at apply, recovery and inspection). INPUT admits leased flows from their exact handoff with the lease's transit source address and a source port in its range for the endpoint's protocol, to the exact endpoint tuple in the live and originally tracked tuple (NEW with a SYN-only TCP opening, or ESTABLISHED), and OUTPUT admits only the ESTABLISHED reply; translated flows and host-origin openings stay denied. The refusal of a platform endpoint on a host address is lifted only for declared ids. Absent and empty keep the previous canonical policy, digest and compiled bytes.
|
|
28
|
+
- Add optional stateful one-way workload grants to the schema-v2 `routerEgress` scope: `workloadGrants` entries `{ protocol, sourceAddress, destinationAddress, destinationPort }` let one veth workload endpoint open one exact port of another. Four constant FORWARD admissions look up the incoming and outgoing link with their addresses in a CONSTANT `workload_link` set and the protocols with the live and originally tracked tuple in a CONSTANT `workload_grant` set, in the default conntrack zone; the destination only answers (ESTABLISHED replies) and can never open toward the source. Up to 1024 grants, sharing the scope's set element budget with host grants. Absent and empty keep the previous canonical policy, digest and compiled bytes.
|
|
29
|
+
|
|
30
|
+
### Maintenance
|
|
31
|
+
|
|
32
|
+
- Bring the release-time tooling current: `@git.zone/tsrust` 1.14.0 → 1.15.0. `@types/node` stays 26.6.1 and pnpm 12.4.2, because their newer releases are younger than the seven-day rule; `@git.zone/cli` 7.2.2, tsbuild 5.0.0, tsrun 3.0.0 and tstest 6.2.0 are already current. The native notices verify unchanged.
|
|
33
|
+
|
|
3
34
|
## 2026-09-24 - 2.5.2
|
|
4
35
|
|
|
5
36
|
### Maintenance
|
|
Binary file
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": "tsrust.build-provenance.v2",
|
|
3
|
-
"binarySha256": "
|
|
3
|
+
"binarySha256": "17c4308039280f584cd51d6cf9030e3c4512746d316561925b6da95bb3c67ff8",
|
|
4
4
|
"buildInfo": {
|
|
5
5
|
"projectName": "@push.rocks/smartnftables",
|
|
6
|
-
"projectVersion": "
|
|
7
|
-
"gitCommit": "
|
|
6
|
+
"projectVersion": "3.0.0",
|
|
7
|
+
"gitCommit": "61c5a8be9c99a83cecde6509fb31c47f43e15bff",
|
|
8
8
|
"gitDirty": false,
|
|
9
|
-
"builtAt": "2026-09-
|
|
10
|
-
"tsrustVersion": "1.
|
|
9
|
+
"builtAt": "2026-09-28T00:27:05.031Z",
|
|
10
|
+
"tsrustVersion": "1.15.1",
|
|
11
11
|
"binary": "smartnftables",
|
|
12
12
|
"target": "linux_amd64_musl"
|
|
13
13
|
}
|
|
Binary file
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": "tsrust.build-provenance.v2",
|
|
3
|
-
"binarySha256": "
|
|
3
|
+
"binarySha256": "3756fe460edc3bdea00c7f598a683081d8238f5172dad9776304a030508d4276",
|
|
4
4
|
"buildInfo": {
|
|
5
5
|
"projectName": "@push.rocks/smartnftables",
|
|
6
|
-
"projectVersion": "
|
|
7
|
-
"gitCommit": "
|
|
6
|
+
"projectVersion": "3.0.0",
|
|
7
|
+
"gitCommit": "61c5a8be9c99a83cecde6509fb31c47f43e15bff",
|
|
8
8
|
"gitDirty": false,
|
|
9
|
-
"builtAt": "2026-09-
|
|
10
|
-
"tsrustVersion": "1.
|
|
9
|
+
"builtAt": "2026-09-28T00:27:15.164Z",
|
|
10
|
+
"tsrustVersion": "1.15.1",
|
|
11
11
|
"binary": "smartnftables",
|
|
12
12
|
"target": "linux_arm64_musl"
|
|
13
13
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartnftables',
|
|
6
|
-
version: '
|
|
6
|
+
version: '3.0.0',
|
|
7
7
|
description: 'A TypeScript module for managing nftables rules including NAT, firewall, and rate limiting with a high-level API.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSwyQkFBMkI7SUFDakMsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLG1IQUFtSDtDQUNqSSxDQUFBIn0=
|
|
@@ -65,9 +65,14 @@ export interface IManagedNftEgressGenerationV2 extends IManagedNftHandoffAllocat
|
|
|
65
65
|
* `transitSourceAddress:transitPort`, this translates on to the workload. */
|
|
66
66
|
export interface IManagedNftRouterPublishedPortV2 {
|
|
67
67
|
protocol: 'tcp' | 'udp';
|
|
68
|
-
/** Published handoff port, 1–65535
|
|
69
|
-
* It is the `targetPort` of the matching host-transit publication. */
|
|
68
|
+
/** Published handoff port, 1–65535; published ports never overlap per protocol across the
|
|
69
|
+
* scope. It is the `targetPort` of the matching host-transit publication. */
|
|
70
70
|
transitPort: number;
|
|
71
|
+
/** Optional last port of a published range `transitPort..transitPortEnd`, greater than
|
|
72
|
+
* `transitPort`. A range keeps every port, so `endpointPort` must equal `transitPort`; like one
|
|
73
|
+
* port it is one interval set element per set, and its translation keeps the port. Absent for
|
|
74
|
+
* one port, which is its only canonical form. */
|
|
75
|
+
transitPortEnd?: number;
|
|
71
76
|
endpointPort: number;
|
|
72
77
|
/** Exact current workload endpoint address behind one veth endpoint of this
|
|
73
78
|
* scope. Never a router-local address, a gateway or a platform endpoint. */
|
|
@@ -75,6 +80,12 @@ export interface IManagedNftRouterPublishedPortV2 {
|
|
|
75
80
|
/** Exact leased transit source address of one current generation, present on
|
|
76
81
|
* `handoff`. No wildcard, secondary-address or route inference. */
|
|
77
82
|
transitSourceAddress: string;
|
|
83
|
+
/** Optional: the workload may open flows from `endpointAddress` and its published endpoint
|
|
84
|
+
* port(s) toward unprotected space, source-translated to `transitSourceAddress` and the
|
|
85
|
+
* published transit port (a range keeps the port). The protected union stays denied, and its
|
|
86
|
+
* endpoint ports may not overlap another publication's on the same address. Absent and
|
|
87
|
+
* `false` are the same canonical policy. */
|
|
88
|
+
symmetric?: boolean;
|
|
78
89
|
}
|
|
79
90
|
/** One exact host-origin flow: the node's own host network namespace dials one port of one local
|
|
80
91
|
* workload at its lease address, from the transit host address of the current handoff. Compile the
|
|
@@ -91,6 +102,21 @@ export interface IManagedNftHostGrant {
|
|
|
91
102
|
/** The workload's exact listening port, 1–65535; never a range. */
|
|
92
103
|
destinationPort: number;
|
|
93
104
|
}
|
|
105
|
+
/** One stateful one-way flow between two workloads behind the same router: the source workload opens
|
|
106
|
+
* connections to one exact port of the destination workload, which may only answer. Both addresses are
|
|
107
|
+
* exact current addresses of two different veth workload endpoints of the scope. It admits the tuple
|
|
108
|
+
* (a TCP opening only with SYN) and its ESTABLISHED replies in the default conntrack zone and nothing
|
|
109
|
+
* else: no reverse opening, no translation and no source-port selection. Grant the reverse direction as
|
|
110
|
+
* a second grant. */
|
|
111
|
+
export interface IManagedNftWorkloadGrant {
|
|
112
|
+
protocol: 'tcp' | 'udp';
|
|
113
|
+
/** Exact unicast address of the dialling workload endpoint, never a prefix. */
|
|
114
|
+
sourceAddress: string;
|
|
115
|
+
/** Exact unicast address of the dialled workload endpoint, never a prefix. */
|
|
116
|
+
destinationAddress: string;
|
|
117
|
+
/** The destination workload's exact listening port, 1–65535; never a range. */
|
|
118
|
+
destinationPort: number;
|
|
119
|
+
}
|
|
94
120
|
/** One combined private/TUN/local/egress table; never compose a second ACCEPT over v1 terminal drops. */
|
|
95
121
|
export interface IManagedNftRouterEgressScopeV2 {
|
|
96
122
|
kind: 'routerEgress';
|
|
@@ -114,17 +140,32 @@ export interface IManagedNftRouterEgressScopeV2 {
|
|
|
114
140
|
* workload. Absent and empty are the same canonical policy, digest and compiled graph; at most 1024,
|
|
115
141
|
* held in a named set behind a constant number of rules. */
|
|
116
142
|
hostGrants?: IManagedNftHostGrant[];
|
|
143
|
+
/** Optional stateful one-way workload-to-workload grants. Absent and empty are the same canonical
|
|
144
|
+
* policy, digest and compiled graph; at most 1024, held in two named sets behind four rules. They
|
|
145
|
+
* share the scope's set element budget with `hostGrants`. */
|
|
146
|
+
workloadGrants?: IManagedNftWorkloadGrant[];
|
|
117
147
|
}
|
|
118
148
|
/** One inbound uplink publication, compiled inside the same host-transit generation. */
|
|
119
149
|
export interface IManagedNftPublishedPortV2 {
|
|
120
150
|
protocol: 'tcp' | 'udp';
|
|
121
|
-
/** Published uplink port, 1–65535
|
|
151
|
+
/** Published uplink port, 1–65535; published ports never overlap per protocol across the scope. */
|
|
122
152
|
hostPort: number;
|
|
153
|
+
/** Optional last port of a published range `hostPort..hostPortEnd`, greater than `hostPort`.
|
|
154
|
+
* A range keeps every port, so `targetPort` must equal `hostPort`; like one port it is one
|
|
155
|
+
* interval set element per set, and its translation keeps the port. Absent for one port, which
|
|
156
|
+
* is its only canonical form. */
|
|
157
|
+
hostPortEnd?: number;
|
|
123
158
|
targetPort: number;
|
|
124
159
|
/** Exact leased transit source address of one current allocation; it selects the handoff. */
|
|
125
160
|
targetAddress: string;
|
|
126
161
|
/** Exact current uplink address that publishes this port. No wildcard or route inference. */
|
|
127
162
|
hostIp: string;
|
|
163
|
+
/** Optional: flows from `targetAddress` and the published target port(s) may leave through the
|
|
164
|
+
* uplink toward unprotected space, source-translated to `hostIp` and the published uplink port
|
|
165
|
+
* (a range keeps the port). The protected union stays denied, its target ports may not fall in
|
|
166
|
+
* a leased range of `targetAddress` or overlap another publication's. Absent and `false` are
|
|
167
|
+
* the same canonical policy. */
|
|
168
|
+
symmetric?: boolean;
|
|
128
169
|
}
|
|
129
170
|
/** Shared-host capture barrier and explicit outer SNAT; Docker forwarding remains a separate owner. */
|
|
130
171
|
export interface IManagedNftHostTransitScopeV2 {
|
|
@@ -147,6 +188,27 @@ export interface IManagedNftHostTransitScopeV2 {
|
|
|
147
188
|
* host-local, a platform endpoint nor a leased transit source address. Absent and empty are the
|
|
148
189
|
* same canonical policy; at most 1024, held in a named set behind a constant number of rules. */
|
|
149
190
|
hostGrants?: IManagedNftHostGrant[];
|
|
191
|
+
/** Optional ids of `protection.platformEndpoints` this host serves itself, on an exact current address
|
|
192
|
+
* of the uplink or of a handoff link (rtnetlink verifies it at apply, recovery and inspection). Only a
|
|
193
|
+
* declared endpoint may hold a host address. Leased flows reach it from their exact handoff with the
|
|
194
|
+
* leased source address and a source port of the allocation's range for the endpoint's protocol; its
|
|
195
|
+
* ESTABLISHED replies return. Absent and empty are the same canonical policy, digest and compiled graph. */
|
|
196
|
+
localPlatformEndpoints?: string[];
|
|
197
|
+
}
|
|
198
|
+
/** One loopback TCP service that only one local user may dial. Every packet the host sends to the
|
|
199
|
+
* exact address and port from a socket of any other user is rejected with a TCP reset, after ordinary
|
|
200
|
+
* output destination NAT; the address and port arriving on any interface but loopback are dropped.
|
|
201
|
+
* The service must bind exactly this address: a wildcard listener stays reachable through others. */
|
|
202
|
+
export interface IManagedNftLocalTcpPortOwner {
|
|
203
|
+
/** Exact IPv4 loopback host address in 127.0.0.0/8, e.g. `127.0.0.1`. Never a prefix or wildcard. */
|
|
204
|
+
address: string;
|
|
205
|
+
/** The service's exact listening port, 1–65535; never a range. */
|
|
206
|
+
port: number;
|
|
207
|
+
/** The only user id whose sockets may send to the port: the socket file's file-system uid as
|
|
208
|
+
* the user namespace owning the network namespace sees it, 0–4294967294. Packets without a socket file carry no uid and
|
|
209
|
+
* are not matched: kernel replies, the teardown of an orphaned socket, and in-kernel sockets such as NFS or CIFS clients,
|
|
210
|
+
* which only privileged mounts create. */
|
|
211
|
+
uid: number;
|
|
150
212
|
}
|
|
151
213
|
/** Host-wide IPv4 destination denial for caller-authenticated private allocation pools.
|
|
152
214
|
* It has no link dependency; exact host grants are its only exceptions. It is not allocation-release or boot-order proof. */
|
|
@@ -159,6 +221,10 @@ export interface IManagedNftAllocationPoolGuardScopeV2 {
|
|
|
159
221
|
* listed pool, and their replies. Absent and empty are the same canonical policy; at most 1024,
|
|
160
222
|
* held in a named set behind a constant number of rules. */
|
|
161
223
|
hostGrants?: IManagedNftHostGrant[];
|
|
224
|
+
/** Optional host-wide loopback port ownership, compiled ahead of the guard in the same table.
|
|
225
|
+
* Absent and empty are the same canonical policy, digest and compiled graph; at most 8, one per
|
|
226
|
+
* exact address and port. */
|
|
227
|
+
localTcpPortOwners?: IManagedNftLocalTcpPortOwner[];
|
|
162
228
|
}
|
|
163
229
|
export interface IManagedNftPolicyV2 {
|
|
164
230
|
schemaVersion: 2;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@push.rocks/smartnftables",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A TypeScript module for managing nftables rules including NAT, firewall, and rate limiting with a high-level API.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
"author": "Task Venture Capital GmbH",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"@git.zone/cli": "7.
|
|
12
|
+
"@git.zone/cli": "7.3.0",
|
|
13
13
|
"@git.zone/tsbuild": "^5.0.0",
|
|
14
|
-
"@git.zone/tsrun": "^3.0.
|
|
15
|
-
"@git.zone/tsrust": "1.
|
|
16
|
-
"@git.zone/tstest": "6.2
|
|
17
|
-
"@types/node": "26.6.
|
|
14
|
+
"@git.zone/tsrun": "^3.0.1",
|
|
15
|
+
"@git.zone/tsrust": "1.15.1",
|
|
16
|
+
"@git.zone/tstest": "6.3.2",
|
|
17
|
+
"@types/node": "26.6.2",
|
|
18
18
|
"typescript": "^7.0.2"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|