pmcf 1.81.1 → 1.83.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 +2 -2
- package/src/dns-utils.mjs +7 -2
- package/src/dns.mjs +101 -67
- package/src/host.mjs +20 -2
- package/src/owner.mjs +25 -11
- package/types/cluster.d.mts +11 -1
- package/types/dns.d.mts +1 -1
- package/types/host.d.mts +9 -0
- package/types/location.d.mts +10 -0
- package/types/network.d.mts +5 -0
- package/types/owner.d.mts +7 -0
- package/types/root.d.mts +10 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmcf",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.83.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"lint:typescript": "tsc --allowJs --checkJs --noEmit --resolveJsonModule --target es2024 --lib esnext -m esnext --module nodenext --moduleResolution nodenext ./src**/*.mjs"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"npm-pkgbuild": "^17.
|
|
41
|
+
"npm-pkgbuild": "^17.5.1",
|
|
42
42
|
"pacc": "^3.3.0",
|
|
43
43
|
"pkg-dir": "^8.0.0"
|
|
44
44
|
},
|
package/src/dns-utils.mjs
CHANGED
|
@@ -5,7 +5,11 @@ export function dnsFullName(name) {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
export function DNSRecord(key, type, ...values) {
|
|
8
|
-
|
|
8
|
+
const pad = type === "MX" ? " " : "";
|
|
9
|
+
|
|
10
|
+
values = values.map(v =>
|
|
11
|
+
typeof v === "number" ? String(v).padStart(3) + pad : v
|
|
12
|
+
);
|
|
9
13
|
|
|
10
14
|
return {
|
|
11
15
|
key,
|
|
@@ -23,7 +27,8 @@ export function dnsFormatParameters(parameters) {
|
|
|
23
27
|
value !== undefined && [...asIterator(value)].length > 0
|
|
24
28
|
? `${name}="${[...asIterator(value)].join(",")}"`
|
|
25
29
|
: name
|
|
26
|
-
)
|
|
30
|
+
)
|
|
31
|
+
.sort((a, b) => a[0].localeCompare(b[0]))
|
|
27
32
|
.join(" ");
|
|
28
33
|
}
|
|
29
34
|
|
package/src/dns.mjs
CHANGED
|
@@ -168,11 +168,19 @@ export class DNSService extends Base {
|
|
|
168
168
|
};
|
|
169
169
|
|
|
170
170
|
result.sources = [
|
|
171
|
-
new FileContentProvider(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
171
|
+
new FileContentProvider(
|
|
172
|
+
p2 + "/",
|
|
173
|
+
{
|
|
174
|
+
mode: 0o644,
|
|
175
|
+
owner: "named",
|
|
176
|
+
group: "named"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
mode: 0o755,
|
|
180
|
+
owner: "named",
|
|
181
|
+
group: "named"
|
|
182
|
+
}
|
|
183
|
+
)[Symbol.asyncIterator]()
|
|
176
184
|
];
|
|
177
185
|
|
|
178
186
|
await generateZoneDefs(this, p2);
|
|
@@ -184,63 +192,86 @@ export class DNSService extends Base {
|
|
|
184
192
|
async function generateZoneDefs(dns, targetDir) {
|
|
185
193
|
const ttl = dns.recordTTL;
|
|
186
194
|
const updates = [Math.ceil(Date.now() / 1000), ...dns.soaUpdates].join(" ");
|
|
195
|
+
const nameService = dns.findService(DNS_SERVICE_FILTER);
|
|
196
|
+
const rname = dns.administratorEmail.replace(/@/, ".");
|
|
197
|
+
|
|
198
|
+
const SOARecord = DNSRecord(
|
|
199
|
+
"@",
|
|
200
|
+
"SOA",
|
|
201
|
+
dnsFullName(nameService.domainName),
|
|
202
|
+
dnsFullName(rname),
|
|
203
|
+
`(${updates})`
|
|
204
|
+
);
|
|
187
205
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const records = new Set();
|
|
194
|
-
|
|
195
|
-
const nameService = dns.findService(DNS_SERVICE_FILTER);
|
|
196
|
-
const rname = dns.administratorEmail.replace(/@/, ".");
|
|
206
|
+
const NSRecord = DNSRecord(
|
|
207
|
+
"@",
|
|
208
|
+
"NS",
|
|
209
|
+
dnsFullName(nameService.ipAddressOrDomainName)
|
|
210
|
+
);
|
|
197
211
|
|
|
198
|
-
|
|
212
|
+
console.log(`${nameService}`, nameService.ipAddressOrDomainName);
|
|
213
|
+
|
|
214
|
+
const configs = [];
|
|
215
|
+
|
|
216
|
+
for (const host of dns.owner.hosts()) {
|
|
217
|
+
for (const domain of host.foreignDomainNames) {
|
|
218
|
+
const zone = {
|
|
219
|
+
id: domain,
|
|
220
|
+
file: `FOREIGN/${domain}.zone`,
|
|
221
|
+
records: new Set([SOARecord, NSRecord])
|
|
222
|
+
};
|
|
223
|
+
const config = {
|
|
224
|
+
name: `${domain}.zone.conf`,
|
|
225
|
+
zones: [zone]
|
|
226
|
+
};
|
|
227
|
+
configs.push(config);
|
|
228
|
+
|
|
229
|
+
for (const address of host.rawAddresses) {
|
|
230
|
+
zone.records.add(
|
|
231
|
+
DNSRecord(
|
|
232
|
+
"@",
|
|
233
|
+
isIPv6Address(address) ? "AAAA" : "A",
|
|
234
|
+
normalizeIPAddress(address)
|
|
235
|
+
)
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
199
240
|
|
|
200
|
-
|
|
201
|
-
|
|
241
|
+
for (const domain of dns.localDomains) {
|
|
242
|
+
const ownerName = dns.owner.name;
|
|
202
243
|
const reverseZones = new Map();
|
|
203
244
|
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
`(${updates})`
|
|
210
|
-
);
|
|
211
|
-
|
|
212
|
-
const NSRecord = DNSRecord(
|
|
213
|
-
"@",
|
|
214
|
-
"NS",
|
|
215
|
-
dnsFullName(nameService.ipAddressOrDomainName)
|
|
216
|
-
);
|
|
245
|
+
const config = {
|
|
246
|
+
name: `${domain}.zone.conf`,
|
|
247
|
+
zones: []
|
|
248
|
+
};
|
|
249
|
+
configs.push(config);
|
|
217
250
|
|
|
218
251
|
const zone = {
|
|
219
252
|
id: domain,
|
|
220
|
-
type: "plain",
|
|
221
253
|
file: `${ownerName}/${domain}.zone`,
|
|
222
|
-
records: new Set([SOARecord, NSRecord
|
|
254
|
+
records: new Set([SOARecord, NSRecord])
|
|
223
255
|
};
|
|
224
|
-
zones.push(zone);
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
zones.push(catalogZone);
|
|
243
|
-
configs.catalog = { name: `catalog.${domain}.zone.conf`, content: [] };
|
|
256
|
+
config.zones.push(zone);
|
|
257
|
+
|
|
258
|
+
if (dns.hasCatalog) {
|
|
259
|
+
const catalogConfig = {
|
|
260
|
+
name: `catalog.${domain}.zone.conf`,
|
|
261
|
+
zones: []
|
|
262
|
+
};
|
|
263
|
+
configs.push(catalogConfig);
|
|
264
|
+
|
|
265
|
+
zone.catalogZone = {
|
|
266
|
+
id: `catalog.${domain}`,
|
|
267
|
+
file: `${ownerName}/catalog.${domain}.zone`,
|
|
268
|
+
records: new Set([
|
|
269
|
+
SOARecord,
|
|
270
|
+
NSRecord,
|
|
271
|
+
DNSRecord(dnsFullName(`version.catalog.${domain}`), "TXT", '"1"')
|
|
272
|
+
])
|
|
273
|
+
};
|
|
274
|
+
catalogConfig.zones.push(zone.catalogZone);
|
|
244
275
|
}
|
|
245
276
|
|
|
246
277
|
const hosts = new Set();
|
|
@@ -279,7 +310,7 @@ async function generateZoneDefs(dns, targetDir) {
|
|
|
279
310
|
file: `${ownerName}/${reverseArpa}.zone`,
|
|
280
311
|
records: new Set([SOARecord, NSRecord])
|
|
281
312
|
};
|
|
282
|
-
zones.push(reverseZone);
|
|
313
|
+
config.zones.push(reverseZone);
|
|
283
314
|
reverseZones.set(subnet.address, reverseZone);
|
|
284
315
|
}
|
|
285
316
|
|
|
@@ -295,7 +326,7 @@ async function generateZoneDefs(dns, targetDir) {
|
|
|
295
326
|
}
|
|
296
327
|
}
|
|
297
328
|
|
|
298
|
-
if (
|
|
329
|
+
if (!hosts.has(host)) {
|
|
299
330
|
hosts.add(host);
|
|
300
331
|
for (const service of host.findServices()) {
|
|
301
332
|
for (const record of service.dnsRecordsForDomainName(
|
|
@@ -308,15 +339,20 @@ async function generateZoneDefs(dns, targetDir) {
|
|
|
308
339
|
}
|
|
309
340
|
}
|
|
310
341
|
}
|
|
342
|
+
}
|
|
311
343
|
|
|
312
|
-
|
|
313
|
-
|
|
344
|
+
for (const config of configs) {
|
|
345
|
+
console.log(`config: ${config.name}`);
|
|
314
346
|
|
|
315
|
-
|
|
347
|
+
const content = [];
|
|
348
|
+
for (const zone of config.zones) {
|
|
349
|
+
console.log(` zone: ${zone.id}`);
|
|
350
|
+
|
|
351
|
+
if (zone.catalogZone) {
|
|
316
352
|
const hash = createHmac("md5", zone.id).digest("hex");
|
|
317
|
-
catalogZone.records.add(
|
|
353
|
+
zone.catalogZone.records.add(
|
|
318
354
|
DNSRecord(
|
|
319
|
-
`${hash}.zones.catalog.${
|
|
355
|
+
`${hash}.zones.catalog.${zone.id}.`,
|
|
320
356
|
"PTR",
|
|
321
357
|
dnsFullName(zone.id)
|
|
322
358
|
)
|
|
@@ -336,7 +372,7 @@ async function generateZoneDefs(dns, targetDir) {
|
|
|
336
372
|
content.push(`};`);
|
|
337
373
|
content.push("");
|
|
338
374
|
|
|
339
|
-
maxKeyLength = 0;
|
|
375
|
+
let maxKeyLength = 0;
|
|
340
376
|
for (const r of zone.records) {
|
|
341
377
|
if (r.key.length > maxKeyLength) {
|
|
342
378
|
maxKeyLength = r.key.length;
|
|
@@ -350,13 +386,11 @@ async function generateZoneDefs(dns, targetDir) {
|
|
|
350
386
|
);
|
|
351
387
|
}
|
|
352
388
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
);
|
|
359
|
-
}
|
|
389
|
+
await writeLines(
|
|
390
|
+
join(targetDir, "etc/named.d/zones"),
|
|
391
|
+
config.name,
|
|
392
|
+
content
|
|
393
|
+
);
|
|
360
394
|
}
|
|
361
395
|
}
|
|
362
396
|
|
package/src/host.mjs
CHANGED
|
@@ -47,6 +47,7 @@ const HostTypeDefinition = {
|
|
|
47
47
|
serial: { type: "string", collection: false, writeable: true },
|
|
48
48
|
vendor: { type: "string", collection: false, writeable: true },
|
|
49
49
|
chassis: { type: "string", collection: false, writeable: true },
|
|
50
|
+
architecture: { type: "string", collection: false, writeable: true },
|
|
50
51
|
priority: { type: "number", collection: false, writeable: true },
|
|
51
52
|
replaces: { type: "string", collection: true, writeable: true },
|
|
52
53
|
depends: { type: "string", collection: true, writeable: true },
|
|
@@ -73,6 +74,7 @@ export class Host extends Base {
|
|
|
73
74
|
#deployment;
|
|
74
75
|
#chassis;
|
|
75
76
|
#vendor;
|
|
77
|
+
#architecture;
|
|
76
78
|
|
|
77
79
|
static {
|
|
78
80
|
addType(this);
|
|
@@ -149,6 +151,14 @@ export class Host extends Base {
|
|
|
149
151
|
return this.#vendor || this.extends.find(e => e.vendor)?.vendor;
|
|
150
152
|
}
|
|
151
153
|
|
|
154
|
+
set architecture(value) {
|
|
155
|
+
this.#architecture = value;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
get architecture() {
|
|
159
|
+
return this.#architecture || this.extends.find(e => e.architecture)?.architecture;
|
|
160
|
+
}
|
|
161
|
+
|
|
152
162
|
get derivedPackaging() {
|
|
153
163
|
return this.extends.reduce((a, c) => a.union(c.packaging), new Set());
|
|
154
164
|
}
|
|
@@ -254,10 +264,18 @@ export class Host extends Base {
|
|
|
254
264
|
return parts[parts.length - 1];
|
|
255
265
|
}
|
|
256
266
|
|
|
257
|
-
get
|
|
267
|
+
get foreignDomainNames() {
|
|
268
|
+
return [...this.aliases].filter(n => n.split(".").length > 1);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
get foreignDomains() {
|
|
258
272
|
return new Set(
|
|
259
273
|
[...this.aliases].map(n => domainFromDominName(n, this.domain))
|
|
260
|
-
)
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
get domains() {
|
|
278
|
+
return this.foreignDomains.union(this.localDomains);
|
|
261
279
|
}
|
|
262
280
|
|
|
263
281
|
get domainNames() {
|
package/src/owner.mjs
CHANGED
|
@@ -30,6 +30,7 @@ const OwnerTypeDefinition = {
|
|
|
30
30
|
domain: { type: "string", collection: false, writeable: true },
|
|
31
31
|
domains: { type: "string", collection: true, writeable: true },
|
|
32
32
|
timezone: { type: "string", collection: false, writeable: true },
|
|
33
|
+
architectures: { type: "string", collection: true, writeable: true },
|
|
33
34
|
locales: { type: "string", collection: true, writeable: true },
|
|
34
35
|
administratorEmail: { type: "string", collection: false, writeable: true }
|
|
35
36
|
}
|
|
@@ -396,25 +397,38 @@ export class Owner extends Base {
|
|
|
396
397
|
return this.domain ? new Set([this.domain]) : new Set();
|
|
397
398
|
}
|
|
398
399
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
let domains = new Set();
|
|
400
|
+
get domainNames() {
|
|
401
|
+
let names = new Set();
|
|
402
402
|
|
|
403
|
-
for (const
|
|
404
|
-
|
|
403
|
+
for (const host of this.hosts()) {
|
|
404
|
+
names = names.union(new Set(host.domainNames));
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
-
return
|
|
407
|
+
return names;
|
|
408
408
|
}
|
|
409
|
-
*/
|
|
410
409
|
|
|
411
|
-
|
|
412
|
-
|
|
410
|
+
#architectures;
|
|
411
|
+
|
|
412
|
+
set architectures(value)
|
|
413
|
+
{
|
|
414
|
+
if (value instanceof Set) {
|
|
415
|
+
this.#architectures = this.#architectures ? this.#architectures.union(value) : value;
|
|
416
|
+
} else {
|
|
417
|
+
this.#architectures = new Set(value);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
get architectures() {
|
|
422
|
+
if(this.#architectures) {
|
|
423
|
+
return this.#architectures;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const architectures = new Set();
|
|
413
427
|
|
|
414
428
|
for (const host of this.hosts()) {
|
|
415
|
-
|
|
429
|
+
architectures.add(host.architecture);
|
|
416
430
|
}
|
|
417
431
|
|
|
418
|
-
return
|
|
432
|
+
return architectures;
|
|
419
433
|
}
|
|
420
434
|
}
|
package/types/cluster.d.mts
CHANGED
|
@@ -193,6 +193,11 @@ export class Cluster extends Host {
|
|
|
193
193
|
collection: boolean;
|
|
194
194
|
writeable: boolean;
|
|
195
195
|
};
|
|
196
|
+
architectures: {
|
|
197
|
+
type: string;
|
|
198
|
+
collection: boolean;
|
|
199
|
+
writeable: boolean;
|
|
200
|
+
};
|
|
196
201
|
locales: {
|
|
197
202
|
type: string;
|
|
198
203
|
collection: boolean;
|
|
@@ -303,6 +308,11 @@ export class Cluster extends Host {
|
|
|
303
308
|
collection: boolean;
|
|
304
309
|
writeable: boolean;
|
|
305
310
|
};
|
|
311
|
+
architecture: {
|
|
312
|
+
type: string;
|
|
313
|
+
collection: boolean;
|
|
314
|
+
writeable: boolean;
|
|
315
|
+
};
|
|
306
316
|
priority: {
|
|
307
317
|
type: string;
|
|
308
318
|
collection: boolean;
|
|
@@ -390,7 +400,7 @@ export class Cluster extends Host {
|
|
|
390
400
|
get backups(): Set<any>;
|
|
391
401
|
get members(): Set<any>;
|
|
392
402
|
preparePackages(stagingDir: any): AsyncGenerator<{
|
|
393
|
-
sources:
|
|
403
|
+
sources: AsyncIterable<import("content-entry").ContentEntry>[];
|
|
394
404
|
outputs: any;
|
|
395
405
|
properties: {
|
|
396
406
|
name: string;
|
package/types/dns.d.mts
CHANGED
|
@@ -92,7 +92,7 @@ export class DNSService extends Base {
|
|
|
92
92
|
LLMNR: string;
|
|
93
93
|
})[];
|
|
94
94
|
preparePackages(stagingDir: any): AsyncGenerator<{
|
|
95
|
-
sources:
|
|
95
|
+
sources: AsyncIterable<import("content-entry").ContentEntry>[];
|
|
96
96
|
outputs: Set<typeof import("npm-pkgbuild").ARCH | typeof import("npm-pkgbuild").DOCKER>;
|
|
97
97
|
properties: {
|
|
98
98
|
name: string;
|
package/types/host.d.mts
CHANGED
|
@@ -96,6 +96,11 @@ export class Host extends Base {
|
|
|
96
96
|
collection: boolean;
|
|
97
97
|
writeable: boolean;
|
|
98
98
|
};
|
|
99
|
+
architecture: {
|
|
100
|
+
type: string;
|
|
101
|
+
collection: boolean;
|
|
102
|
+
writeable: boolean;
|
|
103
|
+
};
|
|
99
104
|
priority: {
|
|
100
105
|
type: string;
|
|
101
106
|
collection: boolean;
|
|
@@ -170,6 +175,8 @@ export class Host extends Base {
|
|
|
170
175
|
get chassis(): any;
|
|
171
176
|
set vendor(value: any);
|
|
172
177
|
get vendor(): any;
|
|
178
|
+
set architecture(value: any);
|
|
179
|
+
get architecture(): any;
|
|
173
180
|
get isTemplate(): true | RegExpMatchArray;
|
|
174
181
|
get isModel(): boolean;
|
|
175
182
|
get model(): any;
|
|
@@ -185,6 +192,8 @@ export class Host extends Base {
|
|
|
185
192
|
get distribution(): any;
|
|
186
193
|
get modelName(): any;
|
|
187
194
|
get hostName(): string;
|
|
195
|
+
get foreignDomainNames(): any[];
|
|
196
|
+
get foreignDomains(): Set<any>;
|
|
188
197
|
get domains(): Set<any>;
|
|
189
198
|
get domainNames(): any[];
|
|
190
199
|
get domainName(): any;
|
package/types/location.d.mts
CHANGED
|
@@ -193,6 +193,11 @@ export class Location extends Owner {
|
|
|
193
193
|
collection: boolean;
|
|
194
194
|
writeable: boolean;
|
|
195
195
|
};
|
|
196
|
+
architectures: {
|
|
197
|
+
type: string;
|
|
198
|
+
collection: boolean;
|
|
199
|
+
writeable: boolean;
|
|
200
|
+
};
|
|
196
201
|
locales: {
|
|
197
202
|
type: string;
|
|
198
203
|
collection: boolean;
|
|
@@ -398,6 +403,11 @@ export class Location extends Owner {
|
|
|
398
403
|
collection: boolean;
|
|
399
404
|
writeable: boolean;
|
|
400
405
|
};
|
|
406
|
+
architectures: {
|
|
407
|
+
type: string;
|
|
408
|
+
collection: boolean;
|
|
409
|
+
writeable: boolean;
|
|
410
|
+
};
|
|
401
411
|
locales: {
|
|
402
412
|
type: string;
|
|
403
413
|
collection: boolean;
|
package/types/network.d.mts
CHANGED
|
@@ -195,6 +195,11 @@ export class Network extends Owner {
|
|
|
195
195
|
collection: boolean;
|
|
196
196
|
writeable: boolean;
|
|
197
197
|
};
|
|
198
|
+
architectures: {
|
|
199
|
+
type: string;
|
|
200
|
+
collection: boolean;
|
|
201
|
+
writeable: boolean;
|
|
202
|
+
};
|
|
198
203
|
locales: {
|
|
199
204
|
type: string;
|
|
200
205
|
collection: boolean;
|
package/types/owner.d.mts
CHANGED
|
@@ -191,6 +191,11 @@ export class Owner extends Base {
|
|
|
191
191
|
collection: boolean;
|
|
192
192
|
writeable: boolean;
|
|
193
193
|
};
|
|
194
|
+
architectures: {
|
|
195
|
+
type: string;
|
|
196
|
+
collection: boolean;
|
|
197
|
+
writeable: boolean;
|
|
198
|
+
};
|
|
194
199
|
locales: {
|
|
195
200
|
type: string;
|
|
196
201
|
collection: boolean;
|
|
@@ -238,6 +243,8 @@ export class Owner extends Base {
|
|
|
238
243
|
get domains(): Set<any>;
|
|
239
244
|
get localDomains(): Set<any>;
|
|
240
245
|
get domainNames(): Set<any>;
|
|
246
|
+
set architectures(value: any);
|
|
247
|
+
get architectures(): any;
|
|
241
248
|
#private;
|
|
242
249
|
}
|
|
243
250
|
import { Base } from "./base.mjs";
|
package/types/root.d.mts
CHANGED
|
@@ -197,6 +197,11 @@ export class Root extends Location {
|
|
|
197
197
|
collection: boolean;
|
|
198
198
|
writeable: boolean;
|
|
199
199
|
};
|
|
200
|
+
architectures: {
|
|
201
|
+
type: string;
|
|
202
|
+
collection: boolean;
|
|
203
|
+
writeable: boolean;
|
|
204
|
+
};
|
|
200
205
|
locales: {
|
|
201
206
|
type: string;
|
|
202
207
|
collection: boolean;
|
|
@@ -402,6 +407,11 @@ export class Root extends Location {
|
|
|
402
407
|
collection: boolean;
|
|
403
408
|
writeable: boolean;
|
|
404
409
|
};
|
|
410
|
+
architectures: {
|
|
411
|
+
type: string;
|
|
412
|
+
collection: boolean;
|
|
413
|
+
writeable: boolean;
|
|
414
|
+
};
|
|
405
415
|
locales: {
|
|
406
416
|
type: string;
|
|
407
417
|
collection: boolean;
|