pmcf 1.2.2 → 1.4.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/package.json +4 -4
- package/src/model.mjs +83 -79
- package/types/model.d.mts +5 -39
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmcf",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -23,21 +23,21 @@
|
|
|
23
23
|
"license": "0BSD",
|
|
24
24
|
"bin": {
|
|
25
25
|
"pmcf-host-defs": "./bin/pmcf-host-defs",
|
|
26
|
+
"pmcf-info": "./bin/pmcf-info",
|
|
26
27
|
"pmcf-location-defs": "./bin/pmcf-location-defs",
|
|
27
28
|
"pmcf-named-defs": "./bin/pmcf-named-defs",
|
|
28
|
-
"pmcf-info": "./bin/pmcf-info",
|
|
29
29
|
"pmcf-network": "./bin/pmcf-network"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"prepare": "node --run prepare:typescript",
|
|
33
|
-
"prepare:typescript": "tsc --allowJs --declaration --emitDeclarationOnly --declarationDir types --resolveJsonModule --target es2024 --lib
|
|
33
|
+
"prepare:typescript": "tsc --allowJs --declaration --emitDeclarationOnly --declarationDir types --resolveJsonModule --target es2024 --lib esnext -m esnext --module nodenext --moduleResolution nodenext --rootDir src ./src**/*.mjs",
|
|
34
34
|
"test": "node --run test:ava",
|
|
35
35
|
"test:ava": "ava --timeout 4m tests/*-ava.mjs tests/*-ava-node.mjs",
|
|
36
36
|
"cover": "c8 -x 'tests/**/*' --temp-directory build/tmp ava --timeout 4m tests/*-ava.mjs tests/*-ava-node.mjs && c8 report -r lcov -o build/coverage --temp-directory build/tmp",
|
|
37
37
|
"docs": "documentation readme --section=API ./src**/*.mjs",
|
|
38
38
|
"lint": "node --run lint:docs && node --run lint:typescript",
|
|
39
39
|
"lint:docs": "documentation lint ./src**/*.mjs",
|
|
40
|
-
"lint:typescript": "tsc --allowJs --checkJs --noEmit --resolveJsonModule --target es2024 --lib
|
|
40
|
+
"lint:typescript": "tsc --allowJs --checkJs --noEmit --resolveJsonModule --target es2024 --lib esnext -m esnext --module nodenext --moduleResolution nodenext ./src**/*.mjs"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "^22.10.7",
|
package/src/model.mjs
CHANGED
|
@@ -18,7 +18,7 @@ export class Base {
|
|
|
18
18
|
return "**/" + this.typeFileName;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
static
|
|
21
|
+
static async prepareData(world, data) {
|
|
22
22
|
return this;
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -96,13 +96,12 @@ export class Base {
|
|
|
96
96
|
return this.typeName + ":" + this.owner.name + "/" + this.name;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
get propertyNames() {
|
|
100
|
+
return ["name", "description", "directory", "owner"];
|
|
101
|
+
}
|
|
102
|
+
|
|
99
103
|
toJSON() {
|
|
100
|
-
return
|
|
101
|
-
name: this.name,
|
|
102
|
-
directory: this.directory,
|
|
103
|
-
owner: this.owner.name,
|
|
104
|
-
description: this.description
|
|
105
|
-
};
|
|
104
|
+
return extractFrom(this, this.propertyNames);
|
|
106
105
|
}
|
|
107
106
|
}
|
|
108
107
|
|
|
@@ -122,23 +121,35 @@ export class World {
|
|
|
122
121
|
return "";
|
|
123
122
|
}
|
|
124
123
|
|
|
124
|
+
async _loadType(name, type) {
|
|
125
|
+
const baseName = type.baseName(name);
|
|
126
|
+
|
|
127
|
+
let object = this.#byName.get(baseName);
|
|
128
|
+
|
|
129
|
+
if (!object) {
|
|
130
|
+
const data = JSON.parse(
|
|
131
|
+
await readFile(
|
|
132
|
+
join(this.directory, baseName, type.typeFileName),
|
|
133
|
+
"utf8"
|
|
134
|
+
)
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
data.name = baseName;
|
|
138
|
+
|
|
139
|
+
type = await type.prepareData(this, data);
|
|
140
|
+
object = new type(this, data);
|
|
141
|
+
this.#byName.set(data.name, object);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return object;
|
|
145
|
+
}
|
|
146
|
+
|
|
125
147
|
async load() {
|
|
126
148
|
for (let type of Object.values(World.types)) {
|
|
127
149
|
for await (const name of glob(type.fileNameGlob, {
|
|
128
150
|
cwd: this.directory
|
|
129
151
|
})) {
|
|
130
|
-
|
|
131
|
-
if (!this.#byName.get(baseName)) {
|
|
132
|
-
const data = JSON.parse(
|
|
133
|
-
await readFile(join(this.directory, name), "utf8")
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
data.name = baseName;
|
|
137
|
-
|
|
138
|
-
type = type.refinedType(data);
|
|
139
|
-
const object = new type(this, data);
|
|
140
|
-
this.#byName.set(data.name, object);
|
|
141
|
-
}
|
|
152
|
+
await this._loadType(name, type);
|
|
142
153
|
}
|
|
143
154
|
}
|
|
144
155
|
}
|
|
@@ -175,34 +186,11 @@ export class World {
|
|
|
175
186
|
}
|
|
176
187
|
|
|
177
188
|
async location(name) {
|
|
178
|
-
|
|
179
|
-
return this.#byName.get(Location.baseName(name));
|
|
189
|
+
return this._loadType(name, Location);
|
|
180
190
|
}
|
|
181
191
|
|
|
182
192
|
async host(name) {
|
|
183
|
-
|
|
184
|
-
return this.#byName.get(Host.baseName(name));
|
|
185
|
-
/*
|
|
186
|
-
if (!data.name) {
|
|
187
|
-
data.name = name;
|
|
188
|
-
} else {
|
|
189
|
-
name = data.name;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (!data.location) {
|
|
193
|
-
const parts = name.split(/\//);
|
|
194
|
-
|
|
195
|
-
if (parts.length > 1 && parts[0] !== "services" && parts[0] !== "model") {
|
|
196
|
-
data.location = parts[0];
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
data.location = await this.location(data.location);
|
|
201
|
-
|
|
202
|
-
if (data.extends) {
|
|
203
|
-
data.extends = await Promise.all(data.extends.map(e => this.host(e)));
|
|
204
|
-
}
|
|
205
|
-
*/
|
|
193
|
+
return this._loadType(name, Host);
|
|
206
194
|
}
|
|
207
195
|
|
|
208
196
|
async *subnets() {
|
|
@@ -238,7 +226,15 @@ export class Host extends Base {
|
|
|
238
226
|
return "host";
|
|
239
227
|
}
|
|
240
228
|
|
|
241
|
-
static
|
|
229
|
+
static async prepareData(world, data) {
|
|
230
|
+
if (data.location) {
|
|
231
|
+
data.location = await world.location(data.location);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (data.extends) {
|
|
235
|
+
data.extends = await Promise.all(data.extends.map(e => world.host(e)));
|
|
236
|
+
}
|
|
237
|
+
|
|
242
238
|
if (data.name?.indexOf("model/") >= 0) {
|
|
243
239
|
return Model;
|
|
244
240
|
}
|
|
@@ -388,24 +384,24 @@ export class Host extends Base {
|
|
|
388
384
|
return readFile(join(this.directory, `ssh_host_${type}_key.pub`), "utf8");
|
|
389
385
|
}
|
|
390
386
|
|
|
387
|
+
get propertyNames() {
|
|
388
|
+
return [
|
|
389
|
+
...super.propertyNames,
|
|
390
|
+
"os",
|
|
391
|
+
"distribution",
|
|
392
|
+
"deployment",
|
|
393
|
+
"master",
|
|
394
|
+
"location",
|
|
395
|
+
"model",
|
|
396
|
+
"replaces",
|
|
397
|
+
"depends",
|
|
398
|
+
"networkInterfaces"
|
|
399
|
+
];
|
|
400
|
+
}
|
|
401
|
+
|
|
391
402
|
toJSON() {
|
|
392
403
|
return {
|
|
393
404
|
...super.toJSON(),
|
|
394
|
-
...Object.fromEntries(
|
|
395
|
-
[
|
|
396
|
-
"location",
|
|
397
|
-
"model",
|
|
398
|
-
"os",
|
|
399
|
-
"distribution",
|
|
400
|
-
"deployment",
|
|
401
|
-
"replaces",
|
|
402
|
-
"depends",
|
|
403
|
-
"master",
|
|
404
|
-
"networkInterfaces"
|
|
405
|
-
]
|
|
406
|
-
.filter(p => this[p])
|
|
407
|
-
.map(p => [p, this[p]])
|
|
408
|
-
),
|
|
409
405
|
extends: this.extends.map(host => host.name),
|
|
410
406
|
services: Object.fromEntries(
|
|
411
407
|
Object.values(this.services).map(s => [s.name, s.toJSON()])
|
|
@@ -574,10 +570,13 @@ export class Location extends Base {
|
|
|
574
570
|
return this.#administratorEmail || "admin@" + this.domain;
|
|
575
571
|
}
|
|
576
572
|
|
|
573
|
+
get propertyNames() {
|
|
574
|
+
return [...super.propertyNames, "domain"];
|
|
575
|
+
}
|
|
576
|
+
|
|
577
577
|
toJSON() {
|
|
578
578
|
return {
|
|
579
579
|
...super.toJSON(),
|
|
580
|
-
domain: this.domain,
|
|
581
580
|
hosts: [...this.#hosts.keys()].sort()
|
|
582
581
|
};
|
|
583
582
|
}
|
|
@@ -627,14 +626,8 @@ export class Network extends Base {
|
|
|
627
626
|
this.#hosts.set(host.name, host);
|
|
628
627
|
}
|
|
629
628
|
|
|
630
|
-
|
|
631
|
-
return
|
|
632
|
-
...super.toJSON(),
|
|
633
|
-
kind: this.kind,
|
|
634
|
-
ipv4: this.ipv4,
|
|
635
|
-
scope: this.scope,
|
|
636
|
-
metric: this.metric
|
|
637
|
-
};
|
|
629
|
+
get propertyNames() {
|
|
630
|
+
return [...super.propertyNames, "kind", "ipv4", "scope", "metric"];
|
|
638
631
|
}
|
|
639
632
|
}
|
|
640
633
|
|
|
@@ -734,16 +727,16 @@ export class Service extends Base {
|
|
|
734
727
|
return this.#type || this.name;
|
|
735
728
|
}
|
|
736
729
|
|
|
737
|
-
|
|
738
|
-
return
|
|
739
|
-
...super.
|
|
740
|
-
ipAddress
|
|
741
|
-
alias
|
|
742
|
-
type
|
|
743
|
-
master
|
|
744
|
-
priority
|
|
745
|
-
weight
|
|
746
|
-
|
|
730
|
+
get propertyNames() {
|
|
731
|
+
return [
|
|
732
|
+
...super.propertyNames,
|
|
733
|
+
"ipAddress",
|
|
734
|
+
"alias",
|
|
735
|
+
"type",
|
|
736
|
+
"master",
|
|
737
|
+
"priority",
|
|
738
|
+
"weight"
|
|
739
|
+
];
|
|
747
740
|
}
|
|
748
741
|
}
|
|
749
742
|
|
|
@@ -776,3 +769,14 @@ export function sectionLines(sectionName, values) {
|
|
|
776
769
|
|
|
777
770
|
return lines;
|
|
778
771
|
}
|
|
772
|
+
|
|
773
|
+
function extractFrom(object, propertyNames) {
|
|
774
|
+
const json = {};
|
|
775
|
+
for (const p of propertyNames) {
|
|
776
|
+
const value = object[p];
|
|
777
|
+
if (value !== undefined) {
|
|
778
|
+
json[p] = value;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
return json;
|
|
782
|
+
}
|
package/types/model.d.mts
CHANGED
|
@@ -4,7 +4,7 @@ export class Base {
|
|
|
4
4
|
static get typeName(): string;
|
|
5
5
|
static get typeFileName(): string;
|
|
6
6
|
static get fileNameGlob(): string;
|
|
7
|
-
static
|
|
7
|
+
static prepareData(world: any, data: any): Promise<typeof Base>;
|
|
8
8
|
static baseName(name: any): any;
|
|
9
9
|
constructor(owner: any, data: any);
|
|
10
10
|
owner: any;
|
|
@@ -17,12 +17,8 @@ export class Base {
|
|
|
17
17
|
get directory(): any;
|
|
18
18
|
expand(object: any): any;
|
|
19
19
|
toString(): string;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
directory: any;
|
|
23
|
-
owner: any;
|
|
24
|
-
description: any;
|
|
25
|
-
};
|
|
20
|
+
get propertyNames(): string[];
|
|
21
|
+
toJSON(): {};
|
|
26
22
|
#private;
|
|
27
23
|
}
|
|
28
24
|
export class World {
|
|
@@ -32,6 +28,7 @@ export class World {
|
|
|
32
28
|
constructor(directory: any);
|
|
33
29
|
directory: any;
|
|
34
30
|
get name(): string;
|
|
31
|
+
_loadType(name: any, type: any): Promise<any>;
|
|
35
32
|
load(): Promise<void>;
|
|
36
33
|
named(name: any): Promise<any>;
|
|
37
34
|
locations(): AsyncGenerator<Location, void, unknown>;
|
|
@@ -47,7 +44,7 @@ export class World {
|
|
|
47
44
|
#private;
|
|
48
45
|
}
|
|
49
46
|
export class Host extends Base {
|
|
50
|
-
static
|
|
47
|
+
static prepareData(world: any, data: any): Promise<typeof Host>;
|
|
51
48
|
networkInterfaces: {};
|
|
52
49
|
services: {};
|
|
53
50
|
postinstall: any[];
|
|
@@ -75,10 +72,6 @@ export class Host extends Base {
|
|
|
75
72
|
toJSON(): {
|
|
76
73
|
extends: any[];
|
|
77
74
|
services: any;
|
|
78
|
-
name: any;
|
|
79
|
-
directory: any;
|
|
80
|
-
owner: any;
|
|
81
|
-
description: any;
|
|
82
75
|
};
|
|
83
76
|
#private;
|
|
84
77
|
}
|
|
@@ -101,12 +94,7 @@ export class Location extends Base {
|
|
|
101
94
|
get dnsRecordTTL(): any;
|
|
102
95
|
get administratorEmail(): any;
|
|
103
96
|
toJSON(): {
|
|
104
|
-
domain: any;
|
|
105
97
|
hosts: any[];
|
|
106
|
-
name: any;
|
|
107
|
-
directory: any;
|
|
108
|
-
owner: any;
|
|
109
|
-
description: any;
|
|
110
98
|
};
|
|
111
99
|
#private;
|
|
112
100
|
}
|
|
@@ -120,16 +108,6 @@ export class Network extends Base {
|
|
|
120
108
|
get subnetAddress(): any;
|
|
121
109
|
hosts(): AsyncGenerator<any, void, unknown>;
|
|
122
110
|
addHost(host: any): void;
|
|
123
|
-
toJSON(): {
|
|
124
|
-
kind: any;
|
|
125
|
-
ipv4: any;
|
|
126
|
-
scope: any;
|
|
127
|
-
metric: any;
|
|
128
|
-
name: any;
|
|
129
|
-
directory: any;
|
|
130
|
-
owner: any;
|
|
131
|
-
description: any;
|
|
132
|
-
};
|
|
133
111
|
#private;
|
|
134
112
|
}
|
|
135
113
|
export class Subnet extends Base {
|
|
@@ -145,17 +123,5 @@ export class Service extends Base {
|
|
|
145
123
|
get weight(): any;
|
|
146
124
|
get master(): any;
|
|
147
125
|
get type(): any;
|
|
148
|
-
toJSON(): {
|
|
149
|
-
ipAddress: any;
|
|
150
|
-
alias: any;
|
|
151
|
-
type: any;
|
|
152
|
-
master: any;
|
|
153
|
-
priority: any;
|
|
154
|
-
weight: any;
|
|
155
|
-
name: any;
|
|
156
|
-
directory: any;
|
|
157
|
-
owner: any;
|
|
158
|
-
description: any;
|
|
159
|
-
};
|
|
160
126
|
#private;
|
|
161
127
|
}
|