@highstate/common 0.14.2 → 0.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.
- package/dist/{chunk-WFWXDYUX.js → chunk-X5BK6JSN.js} +877 -194
- package/dist/chunk-X5BK6JSN.js.map +1 -0
- package/dist/highstate.manifest.json +12 -2
- package/dist/index.js +1 -1
- package/dist/units/databases/etcd-patch/index.js +20 -0
- package/dist/units/databases/etcd-patch/index.js.map +1 -0
- package/dist/units/databases/existing-etcd/index.js +14 -0
- package/dist/units/databases/existing-etcd/index.js.map +1 -0
- package/dist/units/databases/existing-mariadb/index.js +2 -2
- package/dist/units/databases/existing-mariadb/index.js.map +1 -1
- package/dist/units/databases/existing-mongodb/index.js +2 -2
- package/dist/units/databases/existing-mongodb/index.js.map +1 -1
- package/dist/units/databases/existing-postgresql/index.js +2 -2
- package/dist/units/databases/existing-postgresql/index.js.map +1 -1
- package/dist/units/databases/existing-redis/index.js +2 -2
- package/dist/units/databases/existing-redis/index.js.map +1 -1
- package/dist/units/databases/existing-s3/index.js +18 -0
- package/dist/units/databases/existing-s3/index.js.map +1 -0
- package/dist/units/databases/mariadb-patch/index.js +24 -0
- package/dist/units/databases/mariadb-patch/index.js.map +1 -0
- package/dist/units/databases/mongodb-patch/index.js +24 -0
- package/dist/units/databases/mongodb-patch/index.js.map +1 -0
- package/dist/units/databases/postgresql-patch/index.js +24 -0
- package/dist/units/databases/postgresql-patch/index.js.map +1 -0
- package/dist/units/databases/redis-patch/index.js +27 -0
- package/dist/units/databases/redis-patch/index.js.map +1 -0
- package/dist/units/databases/s3-patch/index.js +25 -0
- package/dist/units/databases/s3-patch/index.js.map +1 -0
- package/dist/units/dns/record-set/index.js +14 -20
- package/dist/units/dns/record-set/index.js.map +1 -1
- package/dist/units/existing-server/index.js +3 -4
- package/dist/units/existing-server/index.js.map +1 -1
- package/dist/units/network/address-space/index.js +20 -0
- package/dist/units/network/address-space/index.js.map +1 -0
- package/dist/units/network/endpoint-filter/index.js +15 -0
- package/dist/units/network/endpoint-filter/index.js.map +1 -0
- package/dist/units/network/l3-endpoint/index.js +2 -2
- package/dist/units/network/l3-endpoint/index.js.map +1 -1
- package/dist/units/network/l4-endpoint/index.js +2 -2
- package/dist/units/network/l4-endpoint/index.js.map +1 -1
- package/dist/units/network/l7-endpoint/index.js +12 -0
- package/dist/units/network/l7-endpoint/index.js.map +1 -0
- package/dist/units/script/index.js +1 -1
- package/dist/units/server-patch/index.js +9 -12
- package/dist/units/server-patch/index.js.map +1 -1
- package/dist/units/ssh/key-pair/index.js +1 -1
- package/package.json +64 -10
- package/src/shared/command.ts +1 -1
- package/src/shared/dns.ts +11 -93
- package/src/shared/files.ts +3 -3
- package/src/shared/impl-ref.ts +4 -0
- package/src/shared/index.ts +2 -0
- package/src/shared/network/address-space.spec.ts +114 -0
- package/src/shared/network/address-space.ts +364 -0
- package/src/shared/network/address.spec.ts +109 -0
- package/src/shared/network/address.ts +119 -0
- package/src/shared/network/endpoints.spec.ts +249 -0
- package/src/shared/network/endpoints.ts +608 -0
- package/src/shared/network/index.ts +4 -0
- package/src/shared/network/ip.ts +236 -0
- package/src/shared/network/subnet.spec.ts +62 -0
- package/src/shared/network/subnet.ts +137 -0
- package/src/shared/ssh.ts +1 -1
- package/src/shared/tls.ts +21 -5
- package/src/shared/utils.ts +93 -0
- package/src/units/databases/etcd-patch/index.ts +23 -0
- package/src/units/databases/existing-etcd/index.ts +11 -0
- package/src/units/databases/existing-mariadb/index.ts +1 -1
- package/src/units/databases/existing-mongodb/index.ts +1 -1
- package/src/units/databases/existing-postgresql/index.ts +1 -1
- package/src/units/databases/existing-redis/index.ts +1 -1
- package/src/units/databases/existing-s3/index.ts +1 -1
- package/src/units/databases/mariadb-patch/index.ts +27 -0
- package/src/units/databases/mongodb-patch/index.ts +27 -0
- package/src/units/databases/postgresql-patch/index.ts +27 -0
- package/src/units/databases/redis-patch/index.ts +32 -0
- package/src/units/databases/s3-patch/index.ts +28 -0
- package/src/units/dns/record-set/index.ts +15 -20
- package/src/units/existing-server/index.ts +3 -4
- package/src/units/network/address-space/index.ts +20 -0
- package/src/units/network/endpoint-filter/index.ts +5 -5
- package/src/units/network/l3-endpoint/index.ts +2 -2
- package/src/units/network/l4-endpoint/index.ts +2 -2
- package/src/units/network/l7-endpoint/index.ts +2 -2
- package/src/units/remote-file/index.ts +12 -5
- package/src/units/server-patch/index.ts +10 -13
- package/dist/chunk-WFWXDYUX.js.map +0 -1
- package/dist/units/server-dns/index.js +0 -26
- package/dist/units/server-dns/index.js.map +0 -1
- package/src/shared/network.ts +0 -413
- package/src/units/server-dns/index.ts +0 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@highstate/common",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -20,6 +20,14 @@
|
|
|
20
20
|
"mode": "manual",
|
|
21
21
|
"version": "1"
|
|
22
22
|
},
|
|
23
|
+
"./units/network/address-space": {
|
|
24
|
+
"mode": "manual",
|
|
25
|
+
"version": "1"
|
|
26
|
+
},
|
|
27
|
+
"./units/network/endpoint-filter": {
|
|
28
|
+
"mode": "manual",
|
|
29
|
+
"version": "1"
|
|
30
|
+
},
|
|
23
31
|
"./units/network/l3-endpoint": {
|
|
24
32
|
"mode": "manual",
|
|
25
33
|
"version": "1"
|
|
@@ -28,6 +36,10 @@
|
|
|
28
36
|
"mode": "manual",
|
|
29
37
|
"version": "1"
|
|
30
38
|
},
|
|
39
|
+
"./units/network/l7-endpoint": {
|
|
40
|
+
"mode": "manual",
|
|
41
|
+
"version": "1"
|
|
42
|
+
},
|
|
31
43
|
"./units/existing-server": {
|
|
32
44
|
"mode": "manual",
|
|
33
45
|
"version": "1"
|
|
@@ -40,11 +52,11 @@
|
|
|
40
52
|
"mode": "manual",
|
|
41
53
|
"version": "1"
|
|
42
54
|
},
|
|
43
|
-
"./units/server-
|
|
55
|
+
"./units/server-patch": {
|
|
44
56
|
"mode": "manual",
|
|
45
57
|
"version": "1"
|
|
46
58
|
},
|
|
47
|
-
"./units/
|
|
59
|
+
"./units/databases/existing-etcd": {
|
|
48
60
|
"mode": "manual",
|
|
49
61
|
"version": "1"
|
|
50
62
|
},
|
|
@@ -63,6 +75,34 @@
|
|
|
63
75
|
"./units/databases/existing-redis": {
|
|
64
76
|
"mode": "manual",
|
|
65
77
|
"version": "1"
|
|
78
|
+
},
|
|
79
|
+
"./units/databases/existing-s3": {
|
|
80
|
+
"mode": "manual",
|
|
81
|
+
"version": "1"
|
|
82
|
+
},
|
|
83
|
+
"./units/databases/etcd-patch": {
|
|
84
|
+
"mode": "manual",
|
|
85
|
+
"version": "1"
|
|
86
|
+
},
|
|
87
|
+
"./units/databases/mariadb-patch": {
|
|
88
|
+
"mode": "manual",
|
|
89
|
+
"version": "1"
|
|
90
|
+
},
|
|
91
|
+
"./units/databases/postgresql-patch": {
|
|
92
|
+
"mode": "manual",
|
|
93
|
+
"version": "1"
|
|
94
|
+
},
|
|
95
|
+
"./units/databases/mongodb-patch": {
|
|
96
|
+
"mode": "manual",
|
|
97
|
+
"version": "1"
|
|
98
|
+
},
|
|
99
|
+
"./units/databases/redis-patch": {
|
|
100
|
+
"mode": "manual",
|
|
101
|
+
"version": "1"
|
|
102
|
+
},
|
|
103
|
+
"./units/databases/s3-patch": {
|
|
104
|
+
"mode": "manual",
|
|
105
|
+
"version": "1"
|
|
66
106
|
}
|
|
67
107
|
}
|
|
68
108
|
},
|
|
@@ -73,17 +113,27 @@
|
|
|
73
113
|
},
|
|
74
114
|
"./units/access-point": "./dist/units/access-point/index.js",
|
|
75
115
|
"./units/dns/record-set": "./dist/units/dns/record-set/index.js",
|
|
116
|
+
"./units/network/address-space": "./dist/units/network/address-space/index.js",
|
|
117
|
+
"./units/network/endpoint-filter": "./dist/units/network/endpoint-filter/index.js",
|
|
76
118
|
"./units/network/l3-endpoint": "./dist/units/network/l3-endpoint/index.js",
|
|
77
119
|
"./units/network/l4-endpoint": "./dist/units/network/l4-endpoint/index.js",
|
|
120
|
+
"./units/network/l7-endpoint": "./dist/units/network/l7-endpoint/index.js",
|
|
78
121
|
"./units/existing-server": "./dist/units/existing-server/index.js",
|
|
79
122
|
"./units/ssh/key-pair": "./dist/units/ssh/key-pair/index.js",
|
|
80
123
|
"./units/script": "./dist/units/script/index.js",
|
|
81
|
-
"./units/server-dns": "./dist/units/server-dns/index.js",
|
|
82
124
|
"./units/server-patch": "./dist/units/server-patch/index.js",
|
|
125
|
+
"./units/databases/existing-etcd": "./dist/units/databases/existing-etcd/index.js",
|
|
83
126
|
"./units/databases/existing-mariadb": "./dist/units/databases/existing-mariadb/index.js",
|
|
84
127
|
"./units/databases/existing-postgresql": "./dist/units/databases/existing-postgresql/index.js",
|
|
85
128
|
"./units/databases/existing-mongodb": "./dist/units/databases/existing-mongodb/index.js",
|
|
86
|
-
"./units/databases/existing-redis": "./dist/units/databases/existing-redis/index.js"
|
|
129
|
+
"./units/databases/existing-redis": "./dist/units/databases/existing-redis/index.js",
|
|
130
|
+
"./units/databases/existing-s3": "./dist/units/databases/existing-s3/index.js",
|
|
131
|
+
"./units/databases/etcd-patch": "./dist/units/databases/etcd-patch/index.js",
|
|
132
|
+
"./units/databases/mariadb-patch": "./dist/units/databases/mariadb-patch/index.js",
|
|
133
|
+
"./units/databases/postgresql-patch": "./dist/units/databases/postgresql-patch/index.js",
|
|
134
|
+
"./units/databases/mongodb-patch": "./dist/units/databases/mongodb-patch/index.js",
|
|
135
|
+
"./units/databases/redis-patch": "./dist/units/databases/redis-patch/index.js",
|
|
136
|
+
"./units/databases/s3-patch": "./dist/units/databases/s3-patch/index.js"
|
|
87
137
|
},
|
|
88
138
|
"publishConfig": {
|
|
89
139
|
"access": "public"
|
|
@@ -96,29 +146,33 @@
|
|
|
96
146
|
"dependencies": {
|
|
97
147
|
"@noble/hashes": "^1.7.1",
|
|
98
148
|
"@pulumi/command": "^1.0.2",
|
|
149
|
+
"filter-expression": "^1.0.0",
|
|
150
|
+
"import-meta-resolve": "^4.1.0",
|
|
99
151
|
"micro-key-producer": "^0.7.3",
|
|
100
152
|
"minimatch": "^10.0.3",
|
|
101
153
|
"remeda": "^2.21.0",
|
|
102
154
|
"tar": "^7.4.3",
|
|
103
155
|
"unzipper": "^0.12.3",
|
|
104
|
-
"
|
|
105
|
-
"@highstate/library": "0.
|
|
106
|
-
"@highstate/
|
|
107
|
-
"@highstate/contract": "0.15.0"
|
|
156
|
+
"@highstate/pulumi": "0.17.0",
|
|
157
|
+
"@highstate/library": "0.16.0",
|
|
158
|
+
"@highstate/contract": "0.17.0"
|
|
108
159
|
},
|
|
109
160
|
"devDependencies": {
|
|
110
161
|
"@biomejs/biome": "2.2.0",
|
|
111
162
|
"@types/tar": "^6.1.13",
|
|
112
163
|
"@types/unzipper": "^0.10.11",
|
|
113
164
|
"@typescript/native-preview": "^7.0.0-dev.20250920.1",
|
|
165
|
+
"@vitest/coverage-v8": "2.1.8",
|
|
166
|
+
"vitest": "^3.2.4",
|
|
114
167
|
"type-fest": "^4.41.0",
|
|
115
|
-
"@highstate/cli": "0.
|
|
168
|
+
"@highstate/cli": "0.17.0"
|
|
116
169
|
},
|
|
117
170
|
"repository": {
|
|
118
171
|
"url": "https://github.com/highstate-io/highstate"
|
|
119
172
|
},
|
|
120
173
|
"scripts": {
|
|
121
174
|
"build": "highstate build",
|
|
175
|
+
"test": "vitest run",
|
|
122
176
|
"update-images": "../../../scripts/update-images.sh ./assets/images.json",
|
|
123
177
|
"typecheck": "tsgo --noEmit --skipLibCheck",
|
|
124
178
|
"biome": "biome check --write --unsafe --error-on-warnings",
|
package/src/shared/command.ts
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { sha256 } from "@noble/hashes/sha2"
|
|
14
14
|
import { local, remote, type types } from "@pulumi/command"
|
|
15
15
|
import { flat } from "remeda"
|
|
16
|
-
import { l3EndpointToString } from "./network"
|
|
16
|
+
import { l3EndpointToString } from "./network/endpoints"
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Creates a connection object for the given SSH credentials.
|
package/src/shared/dns.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { dns, network } from "@highstate/library"
|
|
2
2
|
import { getOrCreate, z } from "@highstate/contract"
|
|
3
3
|
import {
|
|
4
4
|
ComponentResource,
|
|
@@ -10,19 +10,12 @@ import {
|
|
|
10
10
|
type Output,
|
|
11
11
|
output,
|
|
12
12
|
type ResourceOptions,
|
|
13
|
-
toPromise,
|
|
14
13
|
type Unwrap,
|
|
15
14
|
} from "@highstate/pulumi"
|
|
16
|
-
import { flat
|
|
15
|
+
import { flat } from "remeda"
|
|
17
16
|
import { Command, type CommandHost } from "./command"
|
|
18
17
|
import { ImplementationMediator } from "./impl-ref"
|
|
19
|
-
import {
|
|
20
|
-
filterEndpoints,
|
|
21
|
-
type InputL3Endpoint,
|
|
22
|
-
l3EndpointToString,
|
|
23
|
-
l34EndpointToString,
|
|
24
|
-
parseL3Endpoint,
|
|
25
|
-
} from "./network"
|
|
18
|
+
import { type InputEndpoint, l3EndpointToString, parseEndpoint } from "./network/endpoints"
|
|
26
19
|
|
|
27
20
|
export const dnsRecordMediator = new ImplementationMediator(
|
|
28
21
|
"dns-record",
|
|
@@ -52,7 +45,7 @@ export type DnsRecordArgs = {
|
|
|
52
45
|
/**
|
|
53
46
|
* The value of the DNS record.
|
|
54
47
|
*/
|
|
55
|
-
value: Input<
|
|
48
|
+
value: Input<InputEndpoint>
|
|
56
49
|
|
|
57
50
|
/**
|
|
58
51
|
* Whether the DNS record is proxied (e.g. to provide DDoS protection).
|
|
@@ -105,12 +98,12 @@ export type DnsRecordSetArgs = Omit<DnsRecordArgs, "provider" | "value"> & {
|
|
|
105
98
|
/**
|
|
106
99
|
* The value of the DNS record.
|
|
107
100
|
*/
|
|
108
|
-
value?: Input<
|
|
101
|
+
value?: Input<InputEndpoint>
|
|
109
102
|
|
|
110
103
|
/**
|
|
111
104
|
* The values of the DNS records.
|
|
112
105
|
*/
|
|
113
|
-
values?: InputArray<
|
|
106
|
+
values?: InputArray<InputEndpoint>
|
|
114
107
|
}
|
|
115
108
|
|
|
116
109
|
function getTypeByEndpoint(endpoint: network.L3Endpoint): string {
|
|
@@ -145,7 +138,7 @@ export class DnsRecord extends ComponentResource {
|
|
|
145
138
|
constructor(name: string, args: DnsRecordArgs, opts?: ResourceOptions) {
|
|
146
139
|
super("highstate:common:DnsRecord", name, args, opts)
|
|
147
140
|
|
|
148
|
-
const l3Endpoint = output(args.value).apply(value =>
|
|
141
|
+
const l3Endpoint = output(args.value).apply(value => parseEndpoint(value))
|
|
149
142
|
const resolvedValue = l3Endpoint.apply(l3EndpointToString)
|
|
150
143
|
const resolvedType = args.type ? output(args.type) : l3Endpoint.apply(getTypeByEndpoint)
|
|
151
144
|
|
|
@@ -238,7 +231,9 @@ export class DnsRecordSet extends ComponentResource {
|
|
|
238
231
|
providers: args.providers,
|
|
239
232
|
name: args.name ?? name,
|
|
240
233
|
}).apply(({ providers, name }) => {
|
|
241
|
-
const matchedProviders = providers.filter(provider =>
|
|
234
|
+
const matchedProviders = providers.filter(provider =>
|
|
235
|
+
provider.zones.some(zone => name.endsWith(zone)),
|
|
236
|
+
)
|
|
242
237
|
|
|
243
238
|
if (matchedProviders.length === 0) {
|
|
244
239
|
throw new Error(`No DNS provider matched the domain "${name}"`)
|
|
@@ -253,7 +248,7 @@ export class DnsRecordSet extends ComponentResource {
|
|
|
253
248
|
providers: matchedProviders,
|
|
254
249
|
}).apply(({ name, providers }) => {
|
|
255
250
|
return providers.flatMap(provider => {
|
|
256
|
-
const l3Endpoint =
|
|
251
|
+
const l3Endpoint = parseEndpoint(value)
|
|
257
252
|
|
|
258
253
|
return new DnsRecord(
|
|
259
254
|
`${name}.${provider.id}.${l3EndpointToString(l3Endpoint)}`,
|
|
@@ -297,80 +292,3 @@ export class DnsRecordSet extends ComponentResource {
|
|
|
297
292
|
)
|
|
298
293
|
}
|
|
299
294
|
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Registers the DNS record set for the given endpoints and prepends the corresponding hostname endpoint to the list.
|
|
303
|
-
*
|
|
304
|
-
* Waits for the DNS record set to be created/updated before continuing.
|
|
305
|
-
*
|
|
306
|
-
* Ignores the "hostname" endpoints in the list.
|
|
307
|
-
*
|
|
308
|
-
* @param endpoints The list of endpoints to register. Will be modified in place.
|
|
309
|
-
* @param fqdn The FQDN to register the DNS record set for. If not provided, no DNS record set will be created and array will not be modified.
|
|
310
|
-
* @param fqdnEndpointFilter The filter to apply to the endpoints before passing them to the DNS record set. Does not apply to the resulted endpoint list.
|
|
311
|
-
* @param patchMode The patch mode to use when modifying the endpoints list.
|
|
312
|
-
* @param dnsProviders The DNS providers to use to create the DNS records.
|
|
313
|
-
* @param dnsSetName The name of the DNS record set. If not provided, the FQDN will be used.
|
|
314
|
-
*/
|
|
315
|
-
export async function updateEndpointsWithFqdn<TEndpoint extends network.L34Endpoint>(
|
|
316
|
-
endpoints: Input<TEndpoint[]>,
|
|
317
|
-
fqdn: string | undefined,
|
|
318
|
-
fqdnEndpointFilter: network.EndpointFilter,
|
|
319
|
-
patchMode: ArrayPatchMode,
|
|
320
|
-
dnsProviders: Input<dns.Provider[]>,
|
|
321
|
-
dnsSetName?: string,
|
|
322
|
-
): Promise<{ endpoints: TEndpoint[]; dnsRecordSet: DnsRecordSet | undefined }> {
|
|
323
|
-
const resolvedEndpoints = await toPromise(endpoints)
|
|
324
|
-
|
|
325
|
-
if (!fqdn) {
|
|
326
|
-
return {
|
|
327
|
-
endpoints: resolvedEndpoints as TEndpoint[],
|
|
328
|
-
dnsRecordSet: undefined,
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
const filteredEndpoints = filterEndpoints(resolvedEndpoints, fqdnEndpointFilter)
|
|
333
|
-
|
|
334
|
-
const dnsRecordSet = new DnsRecordSet(dnsSetName ?? fqdn, {
|
|
335
|
-
name: fqdn,
|
|
336
|
-
providers: dnsProviders,
|
|
337
|
-
values: filteredEndpoints,
|
|
338
|
-
waitAt: "local",
|
|
339
|
-
})
|
|
340
|
-
|
|
341
|
-
const portProtocolGroups = groupBy(filteredEndpoints, endpoint =>
|
|
342
|
-
endpoint.port ? `${endpoint.port}-${endpoint.protocol}` : "",
|
|
343
|
-
)
|
|
344
|
-
|
|
345
|
-
const newEndpoints: TEndpoint[] = []
|
|
346
|
-
|
|
347
|
-
for (const group of Object.values(portProtocolGroups)) {
|
|
348
|
-
newEndpoints.unshift({
|
|
349
|
-
type: "hostname",
|
|
350
|
-
hostname: fqdn,
|
|
351
|
-
visibility: group[0].visibility,
|
|
352
|
-
port: group[0].port,
|
|
353
|
-
protocol: group[0].protocol,
|
|
354
|
-
} as TEndpoint)
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
await toPromise(
|
|
358
|
-
dnsRecordSet.waitCommands.apply(waitCommands => waitCommands.map(command => command.stdout)),
|
|
359
|
-
)
|
|
360
|
-
|
|
361
|
-
if (patchMode === "prepend") {
|
|
362
|
-
return {
|
|
363
|
-
endpoints: uniqueBy(
|
|
364
|
-
//
|
|
365
|
-
[...newEndpoints, ...(resolvedEndpoints as TEndpoint[])],
|
|
366
|
-
endpoint => l34EndpointToString(endpoint),
|
|
367
|
-
),
|
|
368
|
-
dnsRecordSet,
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
return {
|
|
373
|
-
endpoints: newEndpoints,
|
|
374
|
-
dnsRecordSet,
|
|
375
|
-
}
|
|
376
|
-
}
|
package/src/shared/files.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { asset, type Input, toPromise } from "@highstate/pulumi"
|
|
|
11
11
|
import { minimatch } from "minimatch"
|
|
12
12
|
import * as tar from "tar"
|
|
13
13
|
import unzipper from "unzipper"
|
|
14
|
-
import { type InputL7Endpoint, l7EndpointToString,
|
|
14
|
+
import { type InputL7Endpoint, l7EndpointToString, parseEndpoint } from "./network/endpoints"
|
|
15
15
|
|
|
16
16
|
export type FolderPackOptions = {
|
|
17
17
|
/**
|
|
@@ -728,7 +728,7 @@ export async function fetchFileSize(endpoint: network.L7Endpoint): Promise<numbe
|
|
|
728
728
|
* Extracts the name from an L7 endpoint URL without its file extension.
|
|
729
729
|
*/
|
|
730
730
|
export function getNameByEndpoint(endpoint: InputL7Endpoint): string {
|
|
731
|
-
const parsedEndpoint =
|
|
731
|
+
const parsedEndpoint = parseEndpoint(endpoint, 7)
|
|
732
732
|
|
|
733
|
-
return parsedEndpoint.
|
|
733
|
+
return parsedEndpoint.path ? basename(parsedEndpoint.path) : ""
|
|
734
734
|
}
|
package/src/shared/impl-ref.ts
CHANGED
|
@@ -128,3 +128,7 @@ export class ImplementationMediator<
|
|
|
128
128
|
return output(this.call(implRef, input))
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
+
|
|
132
|
+
export function areImplRefsEqual(a: ImplementationReference, b: ImplementationReference): boolean {
|
|
133
|
+
return a.package === b.package && JSON.stringify(a.data) === JSON.stringify(b.data)
|
|
134
|
+
}
|
package/src/shared/index.ts
CHANGED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { network } from "@highstate/library"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
import { parseAddress } from "./address"
|
|
4
|
+
import { createAddressSpace } from "./address-space"
|
|
5
|
+
import { parseEndpoint } from "./endpoints"
|
|
6
|
+
import { subnetToString } from "./subnet"
|
|
7
|
+
|
|
8
|
+
describe("createAddressSpace", () => {
|
|
9
|
+
it("returns a single canonical CIDR for adjacent subnets", () => {
|
|
10
|
+
const result = createAddressSpace({
|
|
11
|
+
included: ["10.0.0.0/25", "10.0.0.128/25"],
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
expect(result.subnets.map(subnetToString)).toEqual(["10.0.0.0/24"])
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it("applies exclusions and keeps canonical ordering", () => {
|
|
18
|
+
const result = createAddressSpace({
|
|
19
|
+
included: ["10.0.0.0/24"],
|
|
20
|
+
excluded: ["10.0.0.64/26"],
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
expect(result.subnets.map(subnetToString)).toEqual(["10.0.0.0/26", "10.0.0.128/25"])
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it("converts dash ranges to a canonical CIDR list", () => {
|
|
27
|
+
const result = createAddressSpace({
|
|
28
|
+
included: ["10.0.0.10-10.0.0.20"],
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
expect(result.subnets.map(subnetToString)).toEqual([
|
|
32
|
+
"10.0.0.10/31",
|
|
33
|
+
"10.0.0.12/30",
|
|
34
|
+
"10.0.0.16/30",
|
|
35
|
+
"10.0.0.20/32",
|
|
36
|
+
])
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it("ignores hostname L3 endpoints", () => {
|
|
40
|
+
const hostnameEndpoint = parseEndpoint("example.com")
|
|
41
|
+
|
|
42
|
+
const result = createAddressSpace({
|
|
43
|
+
included: [hostnameEndpoint],
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
expect(result.subnets).toEqual([])
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it("canonicalizes IPv6 addresses", () => {
|
|
50
|
+
const result = createAddressSpace({
|
|
51
|
+
included: ["2001:db8:0:0:0:0:0:1"],
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
expect(result.subnets.map(subnetToString)).toEqual(["2001:db8::1/128"])
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it("produces a schema-valid address space", () => {
|
|
58
|
+
const result = createAddressSpace({
|
|
59
|
+
included: ["10.0.0.0/24", "2001:db8::1"],
|
|
60
|
+
excluded: ["10.0.0.10"],
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const parsed = network.addressSpaceEntity.schema.safeParse(result)
|
|
64
|
+
expect(parsed.success).toBe(true)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it("accepts network.Subnet inputs", () => {
|
|
68
|
+
const subnet = {
|
|
69
|
+
type: "ipv4",
|
|
70
|
+
baseAddress: "10.1.0.0",
|
|
71
|
+
prefixLength: 24,
|
|
72
|
+
} satisfies network.Subnet
|
|
73
|
+
|
|
74
|
+
const result = createAddressSpace({
|
|
75
|
+
included: [subnet],
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
expect(result.subnets.map(subnetToString)).toEqual(["10.1.0.0/24"])
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it("accepts network.AddressSpace inputs", () => {
|
|
82
|
+
const seed = createAddressSpace({
|
|
83
|
+
included: ["10.2.0.0/25", "10.2.0.128/25"],
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
const addressSpace = seed satisfies network.AddressSpace
|
|
87
|
+
|
|
88
|
+
const result = createAddressSpace({
|
|
89
|
+
included: [addressSpace],
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
expect(result.subnets.map(subnetToString)).toEqual(["10.2.0.0/24"])
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it("accepts network.Address inputs", () => {
|
|
96
|
+
const address = parseAddress("10.3.0.7") satisfies network.Address
|
|
97
|
+
|
|
98
|
+
const result = createAddressSpace({
|
|
99
|
+
included: [address],
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
expect(result.subnets.map(subnetToString)).toEqual(["10.3.0.7/32"])
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it("accepts non-hostname network.L3Endpoint inputs", () => {
|
|
106
|
+
const endpoint = parseEndpoint("10.4.0.9")
|
|
107
|
+
|
|
108
|
+
const result = createAddressSpace({
|
|
109
|
+
included: [endpoint],
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
expect(result.subnets.map(subnetToString)).toEqual(["10.4.0.9/32"])
|
|
113
|
+
})
|
|
114
|
+
})
|