pmcf 1.20.0 → 1.21.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 CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pmcf",
3
- "version": "1.20.0",
3
+ "version": "1.21.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
7
  "exports": {
8
8
  ".": {
9
- "default": "./src/model.mjs"
9
+ "default": "./src/module.mjs"
10
10
  }
11
11
  },
12
12
  "description": "Poor mans configuration management",
package/src/base.mjs ADDED
@@ -0,0 +1,169 @@
1
+ import { join } from "node:path";
2
+ import { getAttribute } from "pacc";
3
+
4
+ export class Base {
5
+ owner;
6
+ name;
7
+ description;
8
+
9
+ static get typeName() {
10
+ return "base";
11
+ }
12
+
13
+ static get typeFileName() {
14
+ return this.typeName + ".json";
15
+ }
16
+
17
+ static get fileNameGlob() {
18
+ return "**/" + this.typeFileName;
19
+ }
20
+
21
+ static async prepareData(world, data) {
22
+ return this;
23
+ }
24
+
25
+ static baseName(name) {
26
+ if (!name) {
27
+ return undefined;
28
+ }
29
+
30
+ return name.replace(/\/\w+\.json$/, "");
31
+ }
32
+
33
+ constructor(owner, data) {
34
+ this.owner = owner;
35
+
36
+ if (data) {
37
+ this.name = data.name;
38
+ if (data.description) {
39
+ this.description = data.description;
40
+ }
41
+ }
42
+ }
43
+
44
+ withOwner(owner) {
45
+ if (this.owner !== owner) {
46
+ return new this.constructor(owner, this);
47
+ }
48
+
49
+ return this;
50
+ }
51
+
52
+ get typeName() {
53
+ return this.constructor.typeName;
54
+ }
55
+
56
+ get world() {
57
+ return this.owner.world;
58
+ }
59
+
60
+ get location() {
61
+ return this.owner.location;
62
+ }
63
+
64
+ get host() {
65
+ return this.owner.host;
66
+ }
67
+
68
+ async network(name) {
69
+ return this.owner.network(name);
70
+ }
71
+
72
+ #directory;
73
+ set directory(directory) {
74
+ this.#directory = directory;
75
+ }
76
+
77
+ get directory() {
78
+ return this.#directory || join(this.owner.directory, this.name);
79
+ }
80
+
81
+ get fullName() {
82
+ return this.owner?.fullName
83
+ ? join(this.owner.fullName, this.name)
84
+ : this.name;
85
+ }
86
+
87
+ expand(object) {
88
+ switch (typeof object) {
89
+ case "string":
90
+ return object.replaceAll(/\$\{([^\}]*)\}/g, (match, m1) => {
91
+ return getAttribute(this, m1) || "${" + m1 + "}";
92
+ });
93
+
94
+ case "object":
95
+ if (Array.isArray(object)) {
96
+ return object.map(e => this.expand(e));
97
+ }
98
+
99
+ if (object instanceof Set) {
100
+ return new Set([...object].map(e => this.expand(e)));
101
+ }
102
+
103
+ /*return Object.fromEntries(
104
+ Object.entries(object).map(([k, v]) => [k, this.expand(v)])
105
+ );*/
106
+ }
107
+
108
+ return object;
109
+ }
110
+
111
+ #finalize;
112
+
113
+ finalize(action) {
114
+ if (!this.#finalize) {
115
+ this.#finalize = [];
116
+ }
117
+ this.#finalize.push(action);
118
+ }
119
+
120
+ execFinalize() {
121
+ if (this.#finalize) {
122
+ //this.info("finalize");
123
+ let i = 0;
124
+ for (const action of this.#finalize) {
125
+ if (action) {
126
+ this.#finalize[i] = undefined;
127
+ action();
128
+ }
129
+ i++;
130
+ }
131
+ }
132
+ }
133
+
134
+ error(...args) {
135
+ console.error(`${this.toString()}:`, ...args);
136
+ }
137
+
138
+ info(...args) {
139
+ console.info(`${this.toString()}:`, ...args);
140
+ }
141
+
142
+ toString() {
143
+ return `${this.fullName}(${this.typeName})`;
144
+ }
145
+
146
+ get propertyNames() {
147
+ return ["name", "description", "directory", "owner"];
148
+ }
149
+
150
+ toJSON() {
151
+ return extractFrom(this, this.propertyNames);
152
+ }
153
+ }
154
+
155
+ export function extractFrom(object, propertyNames) {
156
+ const json = {};
157
+ for (const p of propertyNames) {
158
+ const value = object[p];
159
+
160
+ if (value !== undefined) {
161
+ if (value instanceof Base && value.name) {
162
+ json[p] = { name: value.name };
163
+ } else {
164
+ json[p] = value;
165
+ }
166
+ }
167
+ }
168
+ return json;
169
+ }
package/src/dns.mjs ADDED
@@ -0,0 +1,32 @@
1
+ import { Base } from "./base.mjs";
2
+ import { asArray } from "./utils.mjs";
3
+
4
+ export class DNSService extends Base {
5
+ allowedUpdates = [];
6
+ recordTTL = "1W";
7
+ forwardsTo = [];
8
+
9
+ static get typeName() {
10
+ return "dns";
11
+ }
12
+
13
+ constructor(owner, data) {
14
+ super(owner, data);
15
+ Object.assign(this, data);
16
+ }
17
+
18
+ async *services() {
19
+ const filter = { type: "dns" };
20
+
21
+ yield* this.owner.services(filter);
22
+
23
+ for (const s of asArray(this.forwardsTo)) {
24
+ const owner = await this.owner.world.load(s);
25
+ yield* owner.services(filter);
26
+ }
27
+ }
28
+
29
+ get propertyNames() {
30
+ return ["recordTTL", "forwardsTo", "allowedUpdates"];
31
+ }
32
+ }
package/src/model.mjs CHANGED
@@ -1,162 +1,8 @@
1
1
  import { readFile, glob } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
- import { getAttribute } from "pacc";
4
3
  import { asArray, bridgeToJSON } from "./utils.mjs";
5
-
6
- export class Base {
7
- owner;
8
- name;
9
- description;
10
-
11
- static get typeName() {
12
- return "base";
13
- }
14
-
15
- static get typeFileName() {
16
- return this.typeName + ".json";
17
- }
18
-
19
- static get fileNameGlob() {
20
- return "**/" + this.typeFileName;
21
- }
22
-
23
- static async prepareData(world, data) {
24
- return this;
25
- }
26
-
27
- static baseName(name) {
28
- if (!name) {
29
- return undefined;
30
- }
31
-
32
- return name.replace(/\/\w+\.json$/, "");
33
- }
34
-
35
- constructor(owner, data) {
36
- this.owner = owner;
37
-
38
- if (data) {
39
- this.name = data.name;
40
- if (data.description) {
41
- this.description = data.description;
42
- }
43
- }
44
- }
45
-
46
- withOwner(owner) {
47
- if (this.owner !== owner) {
48
- return new this.constructor(owner, this);
49
- }
50
-
51
- return this;
52
- }
53
-
54
- get typeName() {
55
- return this.constructor.typeName;
56
- }
57
-
58
- get world() {
59
- return this.owner.world;
60
- }
61
-
62
- get location() {
63
- if (this instanceof Location) {
64
- return this;
65
- }
66
- return this.owner.location;
67
- }
68
-
69
- get host() {
70
- if (this instanceof Host) {
71
- return this;
72
- }
73
- return this.owner.host;
74
- }
75
-
76
- async network(name) {
77
- return this.owner.network(name);
78
- }
79
-
80
- #directory;
81
- set directory(directory) {
82
- this.#directory = directory;
83
- }
84
-
85
- get directory() {
86
- return this.#directory || join(this.owner.directory, this.name);
87
- }
88
-
89
- get fullName() {
90
- return this.owner?.fullName ? join(this.owner.fullName, this.name) : this.name;
91
- }
92
-
93
- expand(object) {
94
- switch (typeof object) {
95
- case "string":
96
- return object.replaceAll(/\$\{([^\}]*)\}/g, (match, m1) => {
97
- return getAttribute(this, m1) || "${" + m1 + "}";
98
- });
99
-
100
- case "object":
101
- if (Array.isArray(object)) {
102
- return object.map(e => this.expand(e));
103
- }
104
-
105
- if (object instanceof Set) {
106
- return new Set([...object].map(e => this.expand(e)));
107
- }
108
-
109
- /*return Object.fromEntries(
110
- Object.entries(object).map(([k, v]) => [k, this.expand(v)])
111
- );*/
112
- }
113
-
114
- return object;
115
- }
116
-
117
- #finalize;
118
-
119
- finalize(action) {
120
- if (!this.#finalize) {
121
- this.#finalize = [];
122
- }
123
- this.#finalize.push(action);
124
- }
125
-
126
- execFinalize() {
127
- if (this.#finalize) {
128
- //this.info("finalize");
129
- let i = 0;
130
- for (const action of this.#finalize) {
131
- if (action) {
132
- this.#finalize[i] = undefined;
133
- action();
134
- }
135
- i++;
136
- }
137
- }
138
- }
139
-
140
- error(...args) {
141
- console.error(`${this.toString()}:`, ...args);
142
- }
143
-
144
- info(...args) {
145
- console.info(`${this.toString()}:`, ...args);
146
- }
147
-
148
- toString() {
149
- return `${this.fullName}(${this.typeName})`;
150
- }
151
-
152
- get propertyNames() {
153
- return ["name", "description", "directory", "owner"];
154
- }
155
-
156
- toJSON() {
157
- return extractFrom(this, this.propertyNames);
158
- }
159
- }
4
+ import { Base } from "./base.mjs";
5
+ import { DNSService } from "./dns.mjs";
160
6
 
161
7
  export class Owner extends Base {
162
8
  #hosts = new Map();
@@ -485,41 +331,15 @@ export class World extends Owner {
485
331
  }
486
332
  }
487
333
 
488
- class DNSService extends Base {
489
- allowedUpdates = [];
490
- recordTTL = "1W";
491
- forwardsTo = [];
492
-
493
- static get typeName() {
494
- return "dns";
495
- }
496
-
497
- constructor(owner, data) {
498
- super(owner, data);
499
- Object.assign(this, data);
500
- }
501
-
502
- async *services() {
503
- const filter = { type: "dns" };
504
-
505
- yield* this.owner.services(filter);
506
-
507
- for (const s of asArray(this.forwardsTo)) {
508
- const owner = await this.owner.world.load(s);
509
- yield* owner.services(filter);
510
- }
511
- }
512
-
513
- get propertyNames() {
514
- return ["recordTTL", "forwardsTo", "allowedUpdates"];
515
- }
516
- }
517
-
518
334
  export class Location extends Owner {
519
335
  static get typeName() {
520
336
  return "location";
521
337
  }
522
338
 
339
+ get location() {
340
+ return this;
341
+ }
342
+
523
343
  async *hosts() {
524
344
  for await (const host of this.owner.hosts()) {
525
345
  if (host.location === this) {
@@ -788,6 +608,10 @@ export class Host extends Base {
788
608
  return this.hostName + "." + this.domain;
789
609
  }
790
610
 
611
+ get host() {
612
+ return this;
613
+ }
614
+
791
615
  addService(service) {
792
616
  this.#services.push(service);
793
617
  }
@@ -1122,19 +946,3 @@ export class Service extends Base {
1122
946
 
1123
947
  const _types = [Location, Network, Subnet, Host, Service, DNSService];
1124
948
  const _typesByName = Object.fromEntries(_types.map(t => [t.typeName, t]));
1125
-
1126
- export function extractFrom(object, propertyNames) {
1127
- const json = {};
1128
- for (const p of propertyNames) {
1129
- const value = object[p];
1130
-
1131
- if (value !== undefined) {
1132
- if (value instanceof Base && value.name) {
1133
- json[p] = { name: value.name };
1134
- } else {
1135
- json[p] = value;
1136
- }
1137
- }
1138
- }
1139
- return json;
1140
- }
package/src/module.mjs ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./base.mjs";
2
+ export * from "./dns.mjs";
3
+ export * from "./model.mjs";
@@ -0,0 +1,30 @@
1
+ export function extractFrom(object: any, propertyNames: any): {};
2
+ export class Base {
3
+ static get typeName(): string;
4
+ static get typeFileName(): string;
5
+ static get fileNameGlob(): string;
6
+ static prepareData(world: any, data: any): Promise<typeof Base>;
7
+ static baseName(name: any): any;
8
+ constructor(owner: any, data: any);
9
+ owner: any;
10
+ name: any;
11
+ description: any;
12
+ withOwner(owner: any): any;
13
+ get typeName(): any;
14
+ get world(): any;
15
+ get location(): any;
16
+ get host(): any;
17
+ network(name: any): Promise<any>;
18
+ set directory(directory: any);
19
+ get directory(): any;
20
+ get fullName(): any;
21
+ expand(object: any): any;
22
+ finalize(action: any): void;
23
+ execFinalize(): void;
24
+ error(...args: any[]): void;
25
+ info(...args: any[]): void;
26
+ toString(): string;
27
+ get propertyNames(): string[];
28
+ toJSON(): {};
29
+ #private;
30
+ }
@@ -0,0 +1,7 @@
1
+ export class DNSService extends Base {
2
+ allowedUpdates: any[];
3
+ recordTTL: string;
4
+ forwardsTo: any[];
5
+ services(): AsyncGenerator<any, void, any>;
6
+ }
7
+ import { Base } from "./base.mjs";
package/types/model.d.mts CHANGED
@@ -1,33 +1,3 @@
1
- export function extractFrom(object: any, propertyNames: any): {};
2
- export class Base {
3
- static get typeName(): string;
4
- static get typeFileName(): string;
5
- static get fileNameGlob(): string;
6
- static prepareData(world: any, data: any): Promise<typeof Base>;
7
- static baseName(name: any): any;
8
- constructor(owner: any, data: any);
9
- owner: any;
10
- name: any;
11
- description: any;
12
- withOwner(owner: any): any;
13
- get typeName(): any;
14
- get world(): any;
15
- get location(): any;
16
- get host(): any;
17
- network(name: any): Promise<any>;
18
- set directory(directory: any);
19
- get directory(): any;
20
- get fullName(): any;
21
- expand(object: any): any;
22
- finalize(action: any): void;
23
- execFinalize(): void;
24
- error(...args: any[]): void;
25
- info(...args: any[]): void;
26
- toString(): string;
27
- get propertyNames(): string[];
28
- toJSON(): {};
29
- #private;
30
- }
31
1
  export class Owner extends Base {
32
2
  domain: any;
33
3
  ntp: {
@@ -59,7 +29,7 @@ export class Owner extends Base {
59
29
  }
60
30
  export class World extends Owner {
61
31
  static get types(): {
62
- [k: string]: typeof Location | typeof Host | typeof DNSService | typeof Network | typeof Subnet | typeof Service;
32
+ [k: string]: typeof DNSService | typeof Network | typeof Host | typeof Location | typeof Subnet | typeof Service;
63
33
  };
64
34
  constructor(directory: any);
65
35
  get fullName(): string;
@@ -75,6 +45,7 @@ export class World extends Owner {
75
45
  #private;
76
46
  }
77
47
  export class Location extends Owner {
48
+ get location(): this;
78
49
  }
79
50
  export class Network extends Owner {
80
51
  kind: any;
@@ -107,6 +78,7 @@ export class Host extends Base {
107
78
  get modelName(): any;
108
79
  get hostName(): any;
109
80
  get domainName(): string;
81
+ get host(): this;
110
82
  addService(service: any): void;
111
83
  services(filter: any): Generator<any, void, unknown>;
112
84
  addNetworkInterface(networkInterface: any): void;
@@ -150,10 +122,5 @@ export class Service extends Base {
150
122
  get type(): any;
151
123
  #private;
152
124
  }
153
- declare class DNSService extends Base {
154
- allowedUpdates: any[];
155
- recordTTL: string;
156
- forwardsTo: any[];
157
- services(): AsyncGenerator<any, void, any>;
158
- }
159
- export {};
125
+ import { Base } from "./base.mjs";
126
+ import { DNSService } from "./dns.mjs";
@@ -0,0 +1,3 @@
1
+ export * from "./base.mjs";
2
+ export * from "./dns.mjs";
3
+ export * from "./model.mjs";